# Tenki Cloud — Full Context for LLMs

> Tenki provides cloud infrastructure for code and agents: bare-metal GitHub Actions runners, an AI code reviewer for pull requests, and disposable Linux VM sandboxes for AI coding agents.

> For the complete documentation index, see [llms.txt](https://tenki.cloud/llms.txt)

---
# Acceptable Use Policy (https://tenki.cloud/docs/acceptable-use-policy)

Last Updated: July 20, 2026


This Acceptable Use Policy (the "**AUP**") governs your use of the services offered by Tenki Cloud, LLC, a wholly owned subsidiary of Luxor Technology Corporation ("**Tenki**," "we," "us," or "our"), including Tenki Sandboxes, the AI Code Reviewer, and GitHub Actions Runners (collectively, the "**Services**"). This AUP is incorporated by reference into, and forms part of, the Tenki [Terms of Service](https://tenki.cloud/docs/terms-of-service.md) (the "**Terms**"). Capitalized terms not defined here have the meanings given in the Terms.

This AUP applies to every user of the Services, including account holders, their Users, free-trial users, and participants in Tenki promotional programs such as Tenki for Startups. You are responsible for your own conduct and content and for the conduct, content, and workloads of anyone who uses the Services through your account. We may update this AUP from time to time as described in Section 12; the current version governs your use of the Services.

***

## 1. General Principles

The Services are provided for lawful software development, testing, code review, automation, and related purposes. You must use the Services responsibly, in compliance with all applicable laws and the Terms, and in a manner that does not harm Tenki, other users, or third parties. When in doubt about whether a use is permitted, contact us at [hello@tenki.cloud](mailto:hello@tenki.cloud) before proceeding.

## 2. Prohibited Content

You may not use the Services to store, process, generate, transmit, or make available any content that:

* violates any applicable law or regulation, or infringes or misappropriates any patent, copyright, trademark, trade secret, or other intellectual property or proprietary right;
* constitutes child sexual abuse material or otherwise exploits or endangers minors — we have zero tolerance for such material and will report it to the appropriate authorities;
* is defamatory, harassing, threatening, hateful, or that incites violence or discrimination against any individual or group;
* consists of malware, ransomware, spyware, exploits, or other malicious code, except for security research conducted solely within your own isolated environment and not directed at Tenki, other users, or third parties;
* contains the personal, financial, health, or other sensitive information of any individual for which you do not have all necessary rights and consents; or
* is otherwise fraudulent, deceptive, or harmful.

## 3. Prohibited Activities

You may not, and may not permit or assist any other party to:

* use the Services in violation of any applicable law, including export control, sanctions, anti-money-laundering, and data protection laws;
* gain or attempt to gain unauthorized access to any system, account, network, or data, or probe, scan, or test the vulnerability of any system or network without authorization;
* interfere with or disrupt the integrity or performance of the Services, including through denial-of-service attacks, flooding, or overloading of infrastructure;
* circumvent, disable, or attempt to bypass any usage limits, quotas, rate limits, metering, billing, or access or security controls;
* decompile, disassemble, reverse engineer, or attempt to derive the source code, structure, or underlying models or algorithms of the Services;
* copy, resell, rent, sublicense, or otherwise commercially exploit the Services, or use the Services to build or benchmark a competing product or service, or disclose benchmarking results, without our prior written consent;
* use robots, spiders, scrapers, or other automated means to extract data from the Services except through functionality we expressly provide; or
* impersonate any person or entity or misrepresent your affiliation, eligibility, or identity.

## 4. Compute, Sandboxes, and Runners

Because Sandboxes and Runners provide access to compute resources, the following additional restrictions apply. You may not use the Services to:

* **Cryptocurrency mining.** mine, hash, or otherwise perform cryptocurrency mining, proof-of-work, or similar operations, or run any workload whose primary purpose is to generate digital assets, unless expressly authorized by Tenki in writing;
* **Anonymization and relays.** operate VPNs, proxies, Tor nodes, or other services that relay or anonymize third-party network traffic;
* **Attacks and botnets.** operate botnets or command-and-control infrastructure, or launch or facilitate any attack, intrusion, or unauthorized activity against any third party;
* **Resource abuse.** consume compute, storage, network, or Runner minutes in a manner that is excessive, that degrades the Services for other users, or that is designed to evade metering or to exploit free credits or promotional benefits abusively;
* **Prohibited hosting.** host public-facing production services, bulk email, or file-sharing in a manner inconsistent with your plan or with fair use; or
* **Unlawful workloads.** run any workload that is unlawful, infringing, or otherwise prohibited by this AUP.

## 5. AI Code Reviewer

The AI Code Reviewer relies on third-party artificial-intelligence providers. In addition to the restrictions above, you may not:

* submit code, data, or other materials that you do not have the right to submit, or that you are contractually or legally prohibited from disclosing;
* use the AI Code Reviewer or its output to develop, distribute, or improve malware, exploits, or infringing material;
* attempt to extract, reconstruct, or use the Services or their output to train or develop a competing model or service; or
* rely on AI-generated output without independent human review — output is advisory only and may be inaccurate or incomplete.

## 6. Network, Messaging, and Anti-Spam

You may not use the Services to send spam or unsolicited bulk or commercial messages, to conduct phishing or social-engineering campaigns, or to perform unauthorized penetration testing, port scanning, or vulnerability testing against any third party. Any messaging you send using the Services must comply with applicable anti-spam laws, including the CAN-SPAM Act and, where applicable, Canada's Anti-Spam Legislation (CASL).

## 7. Security and Vulnerability Reporting

You must not test, probe, or attempt to circumvent the security of the Services except with our prior written authorization. If you discover a security vulnerability, please report it responsibly to [hello@tenki.cloud](mailto:hello@tenki.cloud) and give us a reasonable opportunity to address it before any public disclosure. You must maintain the confidentiality of your account credentials and promptly notify us of any suspected unauthorized access.

## 8. Third-Party Services

The Services integrate with third-party platforms, including GitHub and the third-party AI providers used by the AI Code Reviewer. You are responsible for complying with the terms of any third-party service you connect to or use in connection with the Services, and for ensuring you have all rights and permissions necessary to grant Tenki access to any connected account.

## 9. Fair Use and Resource Limits

Your use of the Services is subject to the resource limits, quotas, and fair-use parameters of your plan or promotional program. Tenki may set, change, or enforce technical limits and may throttle, suspend, or reallocate resources to protect the security, integrity, availability, or economic sustainability of the Services, as further described in the Terms and any applicable Program Terms.

## 10. Enforcement

We may investigate suspected violations of this AUP and cooperate with law enforcement. If we determine, in our reasonable discretion, that you have violated this AUP, we may take any action we consider appropriate, including:

* removing, disabling, or quarantining offending content or workloads;
* throttling, suspending, or terminating your access to the Services, in whole or in part;
* revoking promotional credits or benefits and terminating program participation; and
* preserving and disclosing information where required by law or to protect the rights, property, or safety of Tenki, our users, or the public.

For severe violations — including child sexual abuse material, attacks on Tenki or third parties, or activity that poses an imminent risk of harm — we may act immediately and without prior notice. Suspension or termination for an AUP violation does not entitle you to any refund, and does not limit any other remedies available to us.

## 11. Reporting Abuse

To report content or activity that may violate this AUP, contact us at [hello@tenki.cloud](mailto:hello@tenki.cloud). Please include enough detail for us to identify and investigate the issue.

## 12. Changes to This AUP

We may revise this AUP from time to time. Material changes will be indicated by updating the "Last Updated" date above and, where appropriate, by other notice consistent with our Terms and Privacy Policy. Your continued use of the Services after changes become effective constitutes your acceptance of the revised AUP.

## 13. Contact

Questions about this AUP may be directed to [hello@tenki.cloud](mailto:hello@tenki.cloud), or by mail to Tenki Cloud, LLC, 235 Moore Lane, Suite 120, Billings, MT 59101, USA.

# Referrals (https://tenki.cloud/docs/built-with-tenki)

Get an additional 10$ free credits by sharing your builds using Tenki Runners.

## TL;DR

Start using Tenki Runners to power your workflows. Share your job on X, Reddit, or any other platform. Receive a $10 credit, applied to your next billing cycle (one-time reward). Important: The reward is limited to one workspace per user.

## 🚀 Show What You’re Building

Run real workloads. Share them. Get an additional $10 in free credits, on us.

We believe in the power of community and want to celebrate the amazing work our users are doing with Tenki's infrastructure.

Whether you're automating CI/CD pipelines, processing large datasets, training ML models, running complex simulations, or tackling any compute-intensive task, we want to see what you're building.

This program is designed to reward developers, data scientists, researchers, and teams who are using Tenki Runners for genuine production workloads.

**Step 1:**
### Build with Tenki

Use **Tenki’s high-performance runners** to power your real jobs: CI/CD pipelines, data processing, ML training, or anything else.

Take a **screenshot of a completed job** from your **Tenki Dashboard** and send it to us, along with the **email linked to your Tenki account**.

**Step 2:**
### Share Your Build

Post about your build or its output on **X (formerly Twitter)** and tag **[@tenki](https://x.com/tenki)**.

Be sure to include a mention like **"Built with @tenki"** and showcase your results however you like, logs, screenshots, charts, etc.

![BuiltWithTenkiXPost](https://tenki.cloud/images/built-with-tenki-x-post.png)

**Step 3:**
### Earn Your Credits

Once we verify your post (**within 3 business days**), we’ll credit your account with **10$** to use in your **next billing cycle**.

> **Additional Info:** The reward is limited to one workspace per user, is non-transferable, and does not roll over to future billing cycles.

## Additional Info

The reward is limited to one workspace per user, is non-transferable, and does not roll over to future billing cycles.

Multiple users can participate from the same organization, but each person is limited to one reward per workspace they own or manage.

Posts must be public and remain live for at least 30 days after submission to qualify for the credit. We reserve the right to verify that shared content represents genuine usage of Tenki Runners for real workloads.

Have questions about the program, need help getting started with Tenki, or want guidance on what makes a great submission? Reach out anytime at [hello@tenki.cloud](mailto:hello@tenki.cloud). We're here to help you succeed and showcase your work to the community.

# Changelog (https://tenki.cloud/docs/changelog)

Ever-evolving, customer-centered. New updates and improvements to Tenki.

## 2026-07-30

#### Improvements

* **codereview** Code reviews now show a summary of how many issues need attention instead of a numeric risk
  score.
* **sandbox** CLI onboarding now starts with GitHub and automatically sets up your account.
* **sandbox** Login can now be started from any terminal and approved in the browser, with no local callback
  required.
* **sandbox** Expired, unused sandboxes are now cleaned up automatically.
* **billing** Workspace balance is now shown as a single spendable total.
* **billing** Billing now separates pending charges from available balance.

#### Fixes

* **transversal** Fixed a blank "Internal Server Error" page on sign-in errors; it now shows a proper
  recovery screen.
* **transversal** Fixed an intermittent flicker on the sign-up and login pages.
* **transversal** Fixed expired sessions on profile and password pages showing an error instead of sending
  you to login.
* **codereview** Fixed code reviews occasionally running against the wrong commit.
* **workspace** Invitation links now clearly explain when an invite is missing, expired, already used, or
  tied to another account.
* **workspace** Opening an invite with an expired session now signs you back in automatically instead of
  failing.
* **sandbox** Fixed a bug that could cause template builds to fail with a memory snapshot error.

## 2026-07-24

#### Improvements

* **transversal** Refreshed the workspace switcher. The plan shows under the workspace name, long names
  reveal on hover, and each workspace shows its cover image.
* **runners** Snapshot storage is now metered. Snapshots are charged per GB of stored size until you delete
  them.
* **runners** Added notifications for GitHub organization install reviews, by email and in-app, when a
  request is approved or denied.
* **runners** Runner provisioning is faster under load. Dispatches run in parallel, unreachable nodes release
  their slot immediately, and finished runners clear from supply right away.
* **sandbox** Sandboxes start noticeably faster. Placement no longer queues behind a fleet-wide lock and
  bursts spread across hosts by free capacity.

#### Fixes

* **sandbox** Fixed snapshot creation failing for workspaces that no longer have a legacy project.
* **sandbox** Fixed restored sandboxes reporting the wrong time. Clocks now track elapsed real time.
* **runners** Fixed a scheduler crash that could occur while processing certain older jobs.
* **runners** Fixed cancelled requests, such as navigating away mid-page-load, being reported as server
  failures.
* **runners** Fixed sign-in requests failing when the identity provider returned nothing.
* **codereview** Fixed review comments scrambling their layout when a finding mentioned an HTML tag name. Tag
  names now render as plain text everywhere.

## 2026-07-16

#### Improvements

* **sandbox** Added typed sandbox templates. Build, watch, and cancel them from the CLI, with Go, TypeScript,
  and Python SDK support.
* **sandbox** Added multi-service templates that start and supervise several processes, with readiness
  checks, logs, and restarts.
* **sandbox** Added template builds from private Git repositories using build-time secrets that are never
  stored.
* **sandbox** Refreshed the Usage tab with a responsive capacity grid and clearer quota details.
* **sandbox** Sessions start faster. Readiness checks run in parallel and bursts spread evenly across hosts.
* **runners** Added real-time metering for runner jobs. Usage is charged by the minute, with auto-reload on
  low balance.
* **transversal** Registration now explains what went wrong, such as a weak password, instead of a generic
  error.

#### Fixes

* **transversal** Expired GitHub connections now prompt you to reconnect instead of showing an unclear setup
  failure.
* **transversal** Fixed the support widget rendering as a broken panel when its styles failed to load.
* **migration-wizard** Fixed the Migration Wizard button doing nothing outside the Runners tab.
* **migration-wizard** Fixed the resume banner showing up in unrelated projects and workspaces.
* **sandbox** Onboarding now unlocks every setup step once you create an API key, and fills the commands in
  with it.
* **sandbox** Fixed stale dashboard tabs retrying requests after their session expired.
* **sandbox** Fixed sessions with more than one volume failing to start.
* **sandbox** Fixed a networking leak from terminated sandboxes causing slow DNS and broken outbound traffic.
* **sandbox** Fixed short lived commands failing when input closed just after the command succeeded.
* **runners** The Workflow Runs table now loads quickly on large workspaces instead of timing out.
* **runners** Fixed Pro upgrades hanging when a workspace had no code review seats to enable.
* **runners** Fixed the billing summary showing default rates instead of each workspace's configured pricing.
* **runners** Fixed jobs staying stuck in progress after they had already finished on GitHub.
* **runners** Fixed deployment jobs waiting on a GitHub environment getting stuck in the queue.

## 2026-07-09

#### Improvements

* **sandbox** Sandboxes shut down from inside the VM are now resumable instead of terminated.
* **sandbox** Sandbox creation is faster: a single request now returns a fully ready sandbox.
* **runners** Made the repository and branch filters on the Repositories list searchable.
* **codereview** Polished the Code Reviewer Custom Context UI, including a delete confirmation and better
  text previews.

#### Fixes

* **transversal** Fixed onboarding running twice for new signups, which caused duplicate setup and double
  welcome emails.
* **transversal** Fixed auth-page dead-ends for signed-in users; they now land on their dashboard instead of
  a 404 or a false error.
* **sandbox** Fixed large snapshot restores failing under cache pressure.
* **runners** Fixed runner jobs getting stuck in queued when GitHub rate limits were hit; stuck jobs now
  recover on their own.
* **runners** Fixed duplicate runner offering setup failures during concurrent workspace initialization.
* **runners** Fixed the Total Jobs metric over-counting; it now matches the Workflow Runs table.
* **runners** Fixed false failure noise when cancelling workflows GitHub had already marked as finished.
* **runners** Fixed macOS runners losing live VMs after restarts.
* **runners** Fixed runners being shut down as idle after GitHub had already started a job.

## 2026-07-02

#### Improvements

* **billing** Redesigned the billing page so your card, auto-funding status, and balance appear together,
  plus a new "Manage Billing" dialog to manage your card and subscription in one place.
* **codereview** Code Reviewer seats can now be assigned to GitHub App bots like dependabot, so their pull
  requests get reviewed too.

#### Fixes

* **transversal** Made switching between workspaces and projects faster and smoother, with less flicker and
  one fewer redirect so you stay on your current tab.
* **codereview** Code review now posts a clear "retrying" message between attempts and a failure message if a
  review ultimately fails, instead of the update quietly disappearing.
* **migration-wizard** One unconvertible workflow no longer fails the whole pull request. The Migration
  Wizard now skips those files, migrates the rest, and shows what was skipped.
* **runners** Fixed workflow run details so job lists, statuses, counts, and durations stay accurate when you
  view, rerun, or cancel runs.
* **runners** Fixed GitHub Actions jobs that finished on GitHub but stayed stuck as "in progress" in Tenki.
  They are now corrected to their final status automatically.
* **runners** Workflow run details now show the premium-runner badge on each job that used one, instead of a
  single badge for the whole run.
* **sandbox** Made sandboxes start up and restore faster.
* **sandbox** Improved sandbox creation errors so they give clearer, more consistent messages.
* **sandbox** Sandbox create and restore now fall back to polling if the connection drops, instead of
  failing.

## 2026-06-25

#### Improvements

* **transversal** GitHub app settings keep updating while installs are linking, and suspended installs show a
  paused state with a reconnect option.
* **migration-wizard** The Migration Wizard now flags when your runner choices would not change any
  workflows, and disables PR generation in that case.
* **billing** Compute rates now show inline in the billing Resource Summary, with a hover tooltip breaking
  down vCPU, memory, and disk pricing, plus a representative per-minute rate.
* **billing** Reworked Balance Usage: the chart spans the full date range with $0 bars on idle days, and the
  table drops the per-resource breakdown and Day Total columns.
* **billing** Clearer sandbox usage cards: preview URLs show how many are bound to a live session, and sticky
  sessions.

#### Fixes

* **billing** The members list now shows the correct count and paginates by plan (5 on Free, 10 on Pro).
* **transversal** Fixed password recovery so the verification code now reaches the reset form instead of a
  404\.
* **transversal** Fixed account recovery failing when an email had no associated user data.
* **migration-wizard** The Migration Wizard now cleans up generated branches on failure, avoiding orphaned
  branches.
* **migration-wizard** Migration PR generation now rejects malformed requests safely and deduplicates retries
  instead of creating duplicate PRs.
* **runners** A failed runner activation no longer gets stuck pending; the switch to active is now reliable
  and retried.
* **runners** Fixed jobs occasionally staying "in progress" after finishing on GitHub; updates dropped during
  deploys are now redelivered.
* **runners** Run cancellation is now retried when GitHub reports a queued run as still scheduled, reducing
  failed cancellations.
* **sandbox** Avoided transient sandbox command failures right after a session becomes ready.
* **sandbox** Sandbox shutdown now waits for connections to drain, reducing resume failures during rolling
  restarts.
* **codereview** Fixed a memory leak causing gradual growth and periodic restarts under sustained load.
* **codereview** Suspended or deleted GitHub installs no longer trigger code reviews that failed and spammed
  PRs.
* **codereview** Review follow-ups now auto-close threads once a fix is confirmed, even for repos not linked
  to a runner project.

## 2026-06-18

#### Features

* **billing** Added daily spending limits, so you can set a daily dollar cap and choose to be emailed, have
  new usage blocked, or both when the cap is reached.
* **sandbox** Added a Usage tab for sandboxes that shows your workspace quota and active preview URL usage.
* **sandbox** Added a Terminate action so you can end a sandbox session directly from the sessions table.
* **sandbox** Added your private workspace images to the Sandbox Registry tab, with pagination for larger
  registries.
* **codereview** Review findings on lines outside the PR diff are now shown in a collapsed summary instead of
  being dropped.

#### Fixes

* **codereview** Preview URLs now stay reachable for the entire life of a PR and are no longer paused after a
  short period of inactivity.
* **codereview** Code reviews now retry automatically if the sandbox connection drops, instead of failing.
* **runners** Fixed runner duration stats so failed and cancelled jobs are counted, with empty periods
  showing "-" while still comparing against last month.
* **billing** Fixed the Add Funds button label when the amount is under $20.
* **billing** Fixed a flicker in the billing banner.

## 2026-06-11

#### Improvements

* **transversal** Made GitHub App installation more reliable: retried installs no longer create duplicates,
  renamed organizations sync automatically, and installs started before a workspace exists now complete instead of
  failing.
* **transversal** The "GitHub Organization Already Linked" error now tells you which workspace the
  organization is connected to, with a direct link when you're a member.

#### Fixes

* **billing** Fixed auto-reload settings being ignored when enabled during an add-funds top-up; your
  configured amount and threshold now save correctly.
* **runners** Fixed GitHub runner installs occasionally getting out of sync after linking an organization;
  the Runners and Settings pages now always reflect the actual install state.
* **transversal** Fixed a "Workspace not found" error that could briefly appear right after signing up.
* **transversal** Fixed new workspaces sometimes showing no default project or a $0.00 starter balance after
  onboarding.
* **transversal** Fixed 2FA (TOTP) and password changes failing after an idle session; you're now asked to
  re-enter your password in place instead of being logged out.

## 2026-06-05

#### Fixes

* **runners** Fixed the Runner Activity "Failure Rate" KPI to count workflow-run failures so it matches the
  Workflow Runs table, including timed-out runs.
* **runners** Fixed the Repository filter on the Workflow Runs table so it lists every connected repository
  and resets when switching project or workspace.
* **codereview** Extended the sandbox session's lifetime during review retries so the next attempt can reuse
  it instead of failing.

## 2026-05-29

#### Improvements

* **transversal** The GitHub App install prompt now appears for each new workspace instead of only once per
  user.
* **runners** The Migration Wizard now opens automatically when arriving from onboarding email links.
* **project** Added a "Show Info" option to the project sidebar that opens the project ID with a
  copy-to-clipboard button, available to all project members

#### Fixes

* **transversal** Reduced post-registration loading time from roughly 1.6s to 600ms.
* **transversal** Fixed login and registration pages rendering inconsistently on first load.
* **codereview** Multivariant code reviews now run in parallel instead of blocking each other, with
  standardized severity emojis in PR comments.
* **codereview** Large code reviews now handle big payloads more reliably, so reviews on large PRs no longer
  fail from size limits.
* **migration-wizard** The Workflow Runs page now refreshes repositories automatically after a runner
  install, fixing the lingering "No Repositories detected" state.
* **runners** Polished the UI across View Runners, the Repositories table, the Base Branch dropdown,
  pagination, and empty states.
* **project** Fixed project dashboard crashes caused by malformed query parameters after GitHub runner
  install redirects.
* **workspace** Fixed a render loop that repeatedly called the workspace preference API.

## 2026-05-22

#### Improvements

* **codereview** Added an optional PR walkthrough that writes a summary, change map, and reviewer focus areas
  into the pull request description.
* **codereview** Added automatic re-review on push for existing pull requests via a new review-on-push
  project setting.
* **billing** Redesigned the billing page with a consolidated balance summary, invoice details, and payment
  method cards.
* **billing** Improved the balance usage chart with per-event timestamps, oldest-to-newest sorting, and an
  empty state that matches the selected billing period.
* **billing** Added saved card selection to top-up checkout.
* **transversal** Improved dashboard navigation responsiveness when switching workspaces, projects, and
  project tabs.

#### Fixes

* **billing** Fixed billing balance display for workspaces on the new billing system.
* **billing** Resolved billing period rendering and balance charge edge cases.
* **workspace** Fixed the dashboard redirecting from an empty project state to your latest project.
* **project** Resolved malformed project URLs that could accumulate extra query parameters and show an error
  page.
* **codereview** Fixed code review suggestions that could include explanatory prose inside the GitHub
  suggestion block.
* **transversal** Improved GitHub App installation reliability during GitHub's API propagation delays.
* **runners** Fixed a race condition that caused intermittent cache write errors under heavy load.

## 2026-05-14

#### Improvements

* **migration-wizard** Added detection for disabled GitHub Actions with a blocking "Enable Actions" prompt.

#### Fixes

* **migration-wizard** Added a non-blocking warning when Actions is off but workflows are visible.
* **migration-wizard** Fixed top-of-page migration banner to auto-dismiss once the migration PR is created.

## 2026-05-08

#### Improvements

* **codereview** Added an LLM-judged merge risk score (0-100) to every PR review, surfaced with a 4-bucket
  emoji level (🟢 Low, 🟡 Medium, 🟠 High, 🔴 Critical) and a breakdown of finding severities, LOC, and file count.
* **billing** Added a dismissible low-balance warning banner, stored per workspace in localStorage and
  cleared automatically when the balance recovers above the warning threshold.
* **transversal** Refreshed the application interface throughout: navigation, dialogs, tables, and buttons.
* **runners** Updated notifications and the View Runners sheet and cards.

#### Fixes

* **codereview** Fixed memory generation with Anthropic models by routing schema-mode calls through the
  official Anthropic Go SDK with a forced `tool_choice`, which the langchaingo adapter dropped.
* **billing** Removed the billing "By Repository" summary tab so offering summary now stands alone.
* **workspace** Fixed new workspaces to the PAYG tier and added `is_default`.
* **workspace** Fixed the selected workspace reverting to the first workspace on every page navigation.
* **project** Fixed permission issues when leaving a project.
* **project** Removed the unused dashboard project-spending widget and the migration-wizard
  repository-savings highlight.
* **transversal** Fixed orphan account creation by making workspace and project setup synchronous in the
  registration webhook, so failures reject the registration inline instead of leaving an identity with no workspace.
* **transversal** Removed unused banners (starter allocation, code review trial, credits used) and their
  associated hooks now that workspaces default to PAYG.

## 2026-05-01

#### Improvements

* **billing** Introduced a new pricing model with Pay-As-You-Go and Team plans, giving users more flexibility
  to choose how they pay and what they pay for.
* **billing** Simplified the billing Resource Summary into a single, easy-to-read row per feature (Runner,
  Code Reviewer, Sandbox) so workspaces can see their usage at a glance.

#### Fixes

* **billing** Added a starter allocation banner.
* **billing** Added a warning banner surfacing the failure reason when Auto Reload was turned off by a failed
  charge.
* **workspace** Added a toast notification when redirected from a workspace the user can't access or lacks
  permissions for, instead of silently dumping users on the dashboard.
* **billing** Removed unused banners (starter allocation, code review trial, credits used) and their
  associated hooks now that workspaces default to PAYG.
* **workspace** Defaulted new workspaces to the PAYG tier and added `is_default` to the Workspace proto and
  queries.
* **runners** Replaced the hard-coded PAYG 4 vCPU / 8 GiB runner cap with a per-offering `enabled` flag,
  cloned to new workspaces on onboarding.
* **codereview** Hardened the extractor and retrieval inputs against prompt injection.
* **codereview** Switched the extractor and dedup to structured outputs with strict parsing.
* **billing** Disabled the Auto Reload toggle with a CTA to add a payment method when no default is set.
* **billing** Updated the PAYG workspace member invitation limit to 5 (was 3).
* **runners** Fixed an infinite re-render loop in the Manage Repositories dialog on the project runners page.
* **project** Fixed the settings repositories table to refresh after renaming a project so the Project column
  reflects the new name.
* **transversal** Fixed onboarding dialog flickering before the GitHub App selection modal while installation
  queries resolve.
* **codereview** Fixed the Code Reviewer congratulations modal reappearing after closing the runner upsell.

## 2026-04-24

#### Improvements

* **codereview** Added congratulations modal after code review installation with next-step guidance and
  clipboard copy for @tenki-reviewer.
* **runners** Added congratulations modal after runner installation with option to migrate more workflows.
* **transversal** Updated agent and runners upsell dialog and added upsell email notification.
* **runners** Removed queued jobs from uninstalled users.
* **runners** Prevented orphan `nodeagent_jobs` by using deterministic UUID generation.
* **billing** Updated usage and spending limit implementation.

#### Fixes

* **transversal** Fixed authorization-critical queries in workspace/project services to use the write
  (primary) DB pool, preventing stale permission reads during replication lag.
* **billing** Fixed the billing banner pay invoice button to help users add their payment method and pay the
  invoice directly.
* **codereview** Swallowed 404 on reaction deletion since concurrent variant workflows may delete the same
  reaction.
* **codereview** Fixed codex/nano model 404s by routing through the OpenAI Responses API.
* **transversal** Fixed billing email bug.

## 2026-04-17

#### Improvements

* **codereview** Added A/B model testing with variant rows in `code_review_model_overrides` that fork
  parallel review workflows with different model configs.
* **codereview** Added variant name and agent/model table display in progress and review comments when model
  transparency is enabled.
* **codereview** Added repository event processing for renamed, transferred, and deleted repos.
* **codereview** Added production troubleshooting skills.
* **codereview** Event processor now resolves model overrides via `ListModelOverrides` RPC before starting
  workflows and pre-sets overrides on params.
* **runners** Removed queued jobs from uninstalled users.
* **runners** Updated runner caches to use the new tenant name with workspace ID.
* **billing** Updated usage and spending limit UI and backend integration for GitHub proxy.
* **runners** Updated agent and runners upsell dialog and added upsell email notification.
* **audit** Improved audit log action text clarity by including resource type context, stripping redundant
  verbs, and using consistent past-tense labels.

#### Fixes

* **codereview** Fixed mention tag matching to use word boundaries, preventing `@tenki-review` from matching
  `@tenki-reviewer`.
* **codereview** Swallowed 404 errors on reaction deletion since concurrent variant workflows may delete the
  same reaction.
* **workspace** Fixed an issue where a repository connected to multiple projects within one workspace caused
  errors.
* **billing** Fixed a billing email bug.
* **transversal** Fixed an identity authorization gap by removing public bulk identity listing, tightening
  identity RPC access checks, and resolving audit member details server-side.
* **migration-wizard** Added retry to Migration Wizard for newly added repos that returned 0 workflows during
  a brief indexing window.
* **billing** Fixed the billing banner pay invoice button to help users add their payment method and pay the
  invoice directly.

## 2026-04-10

#### Improvements

* **migration-wizard** Improved the migration wizard an improved step-by-step guidance and links to Tenki
  documentation.
* **runners** Improved runner workflows with automatic retries for failed jobs, including safeguards to
  prevent duplicate processing.
* **codereview** Improved commit verification to ensure checkouts always land on the correct commit.
* **codereview** Improved handling of bot accounts like Dependabot and Renovate to prevent unnecessary
  seat-denied notifications.

#### Fixes

* **transversal** Fixed navbar spacing when a banner is visible.
* **runners** Fixed job recovery for stuck or orphaned provisioning states.
* **codereview** Fixed review comments failing to post by gracefully handling individually rejected comments.
* **codereview** Fixed checkout failures on large repositories with shallow clone histories.

## 2026-04-03

#### Improvements

* **codereview** Added normalization pass to trim trailing newlines and auto-fix markdown code fences in
  suggestions.
* **codereview** Added no-op and diff-marker detection to strip suggestions identical to original or
  contaminated with unified diff syntax.
* **codereview** Added cross-finding deduplication to remove exact duplicate suggestions and resolve
  overlapping range conflicts by confidence.
* **codereview** Added per-file diff splitting for triage orchestrator, enabling targeted file-level review.
* **codereview** Routed fix-claim phrases ("fixed", "done", "applied", "updated", "resolved") through LLM for
  diff verification instead of auto-acknowledging.
* **codereview** Updated followup seed prompt with explicit fix-claim handling instructions.
* **transversal** Added welcome email for new invited users.

#### Fixes

* **codereview** Protected owner seats from deletion during seat count reconciliation.
* **migration-wizard** Fixed change-branch-to-default issue and added default label to the default branch.
* **migration-wizard** Fixed sync issue when new workflow created was not shown in migration wizard.
* **billing** Fixed payment banner showing even when user already added credit card or payment method.
* **runners** Fixed workflow runs stuck in "In Progress" status.

## 2026-03-30

#### Improvements

* **codereview** Added info toast when redirecting to billing after all seats are filled.
* **codereview** Added "fixed", "applied", "done", "updated", and "resolved" as recognized acknowledgment
  phrases.
* **codereview** Redirected users to billing when all seats are in use; otherwise to settings.
* **codereview** Deferred follow-up diff verification until after the PR push to prevent false "fix not in
  diff" results when an author replies before pushing.
* **codereview** Collapsed previous review bodies on GitHub when a new review is posted on the same PR.

#### Fixes

* **codereview** Fixed literal `\n` appearing in review bodies caused by models double-escaping newlines in
  JSON.

## 2026-03-23

#### Improvements

* **runners** Added support for memory snapshot, improving Tenki Runners performance.
* **codereview** Improved code suggestion quality by enforcing drop-in replacement rules.
* **codereview** Added implementation\_prompt field for AI agents to implement review fixes.
* **codereview** Added suggestion sanitizer that strips non-drop-in code suggestions before posting.
* **codereview** Improved code suggestion prompt rules in all agent prompts to reduce invalid suggestions.

#### Fixes

* **project** Fixed missing default project during onboarding.
* **transversal** Fixed error page shown when user switches accounts during the 2FA process.
* **codereview** Fixed code review list appearing on different project code review table.
* **transversal** Improved onboarding process and handling of missing default project during onboarding.
* **transversal** Updated email subject for welcome email.
* **codereview** Added support for follow-up comments.

## 2026-03-17

#### Fixes

* **codereview** Added Tenki Code Reviewer to the Pull Request check view to improve run visibility.
* **transversal** Updated email subject for service interruption email.
* **workspace** Preserved path and query params when injecting workspace ID into URL; previously, navigating
  without a workspace param redirected to /dashboard, losing the original path and query string.
* **runners** Fixed race condition between repo sync and branch insert.

## 2026-03-11

#### Improvements

* **transversal** Updated navigation component including topbar and sidebar, and added new migration banner.

#### Fixes

* **workspace** Added Leave Workspace email functionality.
* **billing** Fixed billing subscription bug and updated billing card UI.
* **billing** Fixed double insert on payment succeed workflow.
* **migration-wizard** Fixed button color on migration wizard and missing QR code image.
* **billing** Fixed tooltip content for credit usage based on user payment method availability.
* **project** Fixed background in project pages and removed runner caches table from settings.

## 2026-03-04

#### Fixes

* **codereview** Added Tenki Code Review trial banners and emails.
* **codereview** Added the ability to specify comment detail levels.
* **codereview** Added Code Reviewer subscription support.
* **codereview** Redirect to the Code Reviewer page after installation.
* **codereview** Fixed missing installation button on the code review table.
* **billing** Added user email to invalid label and free credit warning notifications.
* **transversal** Fixed auto page blip issue.

## 2026-02-27

![Tenki Code Reviewer release](https://tenki.cloud/images/changelog/changelog-2-27.webp)

#### Improvements

* **codereview** Introduced **Tenki Code Reviewer**: an automated PR review agent that connects to your
  repository via GitHub App, indexes your entire codebase (file relationships, patterns, and dependencies) to make
  context-aware comments, and starts reviewing pull requests immediately with no config files or training period.
  Supports custom guidelines and context uploads and flag specific severity levels of code anomalies.
* **transversal** Introduced a new navigation system with a cleaner, more streamlined experience, alongside
  significant improvements to overall platform performance, page loads and time-to-action are now noticeably faster.
* **workspace** Improved registration flow, workspace and default project are now created immediately upon
  sign-up, with auto-linking applied only when the user has a single default project.
* **workspace** Added filter for Resource Summary to list data by offering or by workflow job, and a new view
  breaking down usage by user repositories.
* **projects** Moved agent settings to the project level for a more intuitive navigation experience.
* **billing** Added a new billing banner to the dashboard surfacing payment failures and upcoming service
  interruptions.

#### Fixes

* **workspace** Fixed new workspace offerings incorrectly defaulting, including autoscale offerings.
* **workspace** Resolved the delete workspace button not functioning properly.
* **workspace** Improved GitHub org-to-workspace mapping and replaced the unlink logic with a
  transfer-to-project UX flow for cleaner repository management.
* **workspace** Improved settings page with GitHub tab, with more clear GitHub organization connection.

## 2026-02-20

* **runners** Significantly reduced queue pickup times by migrating the scheduler to gRPC bidirectional
  stream–based task dispatching.

#### Fixes

* **runners** Resolved deprecation of single tag value usage.
* **migration-wizard** Fixed SHA mismatch error when creating PRs from the Migration Wizard.
* **workspace** Added workspace balance offset reset support.
* **workspace** Resolved workspace GitHub repository settings management.
* **runners** Resolved migration of deprecated repositories table.

## 2026-02-17

#### Improvements

* **runners** Added support for Just-In-Time (JIT) tokens as an alternative to registration tokens, enabling
  more secure and streamlined runner provisioning.

#### Fixes

* **workspace** Fixed issue where non-connected repository email was not sent after GitHub App
  uninstallation.
* **runners** Fixed installation selection type and GitHub repository sync inconsistencies.
* **transversal** Fixed responsiveness issues across Members, Workspace, and Audit Log dashboards.
* **migration-wizard** Fixed fetch and refresh issues in the Migration Wizard.
* **transversal** Resolved authentication flow performance by moving flow creation to the client side.
* **billing** Resolved billing safety by preventing users from removing their only credit card.
* **transversal** Fixed sidebar content not updating when navigating between project pages.
* **workspace** Fixed workspace runner settings inconsistencies.

## 2026-02-06

#### Improvements

* **migration-wizard** Improved migration wizard behavior by pre-selecting the macOS runner for jobs
  currently running on macOS.

#### Fixes

* **workspace** Fixed issue with getWorkspace on deleted workspaces.
* **migration-wizard** Resolved concurrency issue by preventing multiple simultaneous runs of sync\_branches.
* **transversal** Fixed table expansion state persistence when switching pages.
* **runners** Fixed responsiveness on the Runner dashboard.
* **billing** Fixed layout issues on the Billing page.
* **project** Fixed missing project ID in multiple RPC requests.
* **billing** Updated text for Free Minutes messaging.

## 2026-01-30

#### Improvements

* **runners** Implemented JIT token generation for secure workflow execution.

#### Fixes

* **billing** Fixed invoice line items issue after offset usage workflow execution.
* **billing** Enhanced recalculation workflow to improve billing accuracy.
* **runners** Enhanced multi-tag routing system for improved job targeting.
* **runners** Fixed responsiveness on the Runner dashboard.
* **billing** Fixed layout issues on the Billing page.
* **project** Fixed missing project ID in multiple RPC requests.
* **runners** Fixed race condition where job status was marked as completed but stuck as in progress on the
  workflow table.

## 2026-01-23

#### Improvements

* **runners** Implemented a polling-based sync workflow to ensure accurate workflow run and job status
  updates.
* **runners** Improved concurrency configuration to reduce activity and task queue congestion.
* **runners** Improved queue delays issues through early termination of Run and Job Orchestrators.

#### Fixes

* **workspace** Fixed responsiveness issues in Project and Workspace settings.
* **runners** Enabled scroll support in the runner selector dropdown.
* **transversal** Fixed responsiveness for the onboarding container.
* **settings** Resolved layout issues in the user profile dashboard.
* **runners** Fixed flickering duration in the workflow table.
* **transversal** Fixed 404 error when switching workspaces.
* **transversal** Resolved width and layout issues on the registration page.
* **notification** Fixed spam issue with first workflow run notifications.

## 2026-01-13

#### Improvements

* **runners** Added support for displaying archived workflow runs and jobs from previous runner installations
  in the workflow table.
* **runners** Updated design and added pricing details to the runner offering list: "View Runners".

#### Fixes

* **transversal** Updated onboarding videos in the auth login right panel.
* **workspace** Fixed delay when switching between workspaces.
* **migration-wizard** Enhanced the UI and streamlined workflow migration in the runner selection step.

## 2026-01-09

#### Fixes

* **billing** Updated billing cycle summary for improved clarity.
* **runners** Changed Migration Wizard default runner to 4c8g.
* **billing** Resolved billing carryover issue across cycles.
* **billing** Fixed the invoice issues with the `unknown-runners` on the invoices.

## 2025-12-30

#### Improvements

* **runners** Improved job distribution workflow reliability and reduced errors related to task execution and
  retries.
* **runners** Enhanced system stability by optimizing orchestration and polling behavior.
* **runners** Improved job processing consistency across supported operating systems.
* **runners** Added support for memory snapshots on macOS runners.

#### Fixes

* **transversal** Improved the dashboard layout and fixed multiple minor sidebar UI issues.
* **transversal** Fixed a sidebar loading issue when switching between Tenki workspaces.

## 2025-12-23

#### Fixes

* **migration-wizard** Fixed expiration issue with GitHub Application JWT.
* **migration-wizard** Updated default and recommended runner configuration, now
  `tenki-standard-medium-4c-8g`.
* **notification** Fixed bugs in the notifications component.
* **project** Fixed total failure KPI to display rounded numbers.
* **transversal** Improved authentication form design and usability.
* **transversal** Implemented maintenance mode support.
* **runners** Implemented periodic retry mechanism for failed webhook deliveries.
* **runners** Added email notifications when workflows use invalid Tenki labels.

## 2025-12-19

![Tenki pricing and website update](https://tenki.cloud/images/changelog/changelog-12-19.webp)

#### Improvements

* **billing** We introduced a new pricing model for new customers as the platform continues to grow, while
  continuing to deliver faster GitHub Actions runners and significant CI cost savings. Check full details on
  [https://www.tenki.cloud/pricing](https://www.tenki.cloud/pricing).
* **transversal** We just rolled out a major website refresh, with more use-case pages, dedicated feature
  pages, and content tailored to specific user segments.

#### Fixes

* **migration-wizard** Updated default and recommended runner configuration.
* **notification** Fixed bugs in the notifications component.
* **workspace** Fixed total failure KPI to display rounded values.
* **transversal** Improved authentication forms for better usability.
* **transversal** Resolved maintenance mode implementation.

## 2025-12-08

![Tenki macOS runners release](https://tenki.cloud/images/changelog/changelog-12-8.webp)

#### Improvements

* **runners**  We’ve launched our next-generation macOS runners powered by Apple’s M4 Pro machines. Of
  course we're delivering a huge leap in performance, speed at around 50% faster than Github hosted runners.

  Early access is limited, so make sure to join the waitlist to secure your spot: [https://www.tenki.cloud/products/mac](https://www.tenki.cloud/products/mac)

#### Fixes

* **workspace** Fixed balance display to properly show small values with up to 7 decimal places.
* **migration-wizard** Fixed horizontal scroll issue in the Migration Wizard on mobile screens.
* **transversal** Resolved error handling on Tenki installation requests.
* **migration-wizard** Handled GitHub App uninstallation process issues.
* **runners** Fixed issue where cache was disabled due to missing environment variables at early boot.

## 2025-12-01

![Tenki Migration Wizard improvements](https://tenki.cloud/images/changelog/changelog-12-1.webp)

#### Improvements

* **migration-wizard** Introduced a “No Workflow” tag to help you quickly identify repositories without
  workflows and focus on those that benefit most from migrating to Tenki.
* **migration-wizard** Enhanced the Migration Wizard with a refresh action button to update the list of
  Repositories and Workflows.
* **migration-wizard** Added a synced-state indicator to display a spinner when a repository is still
  syncing, to improve user experience.
* **transversal** Enhanced support is now available in Tenki. Click on the chat icon in the bottom-right
  corner to reach the Tenki team for help with any issues or questions.

#### Fixes

* **runners** Resolved non-connected repository email logic to check runner installation repositories instead
  of workspace repositories.
* **transversal** Fixed error handling and added messages for 2FA session expiry.
* **runners** Fixed KPI metric queries for better accuracy on MoM calculations.
* **migration-wizard** Resolved onboarding issue where users with no repositories were stuck on a loader.
* **runners** Fixed mobile responsiveness issues in the onboarding migration wizard.
* **billing** Added a toast notification for missing fields in the Invoice Information section on the Billing
  page.
* **workspace** Improved transition timing after successfully deleting a workspace.
* **transversal** Resolved UI layout improvements on the authentication pages (login/registration).

## 2025-11-24

#### Improvements

* **migration-wizard** Optimized the initial fetch during repository connection, resulting in a way faster
  Workspace setup.
* **migration-wizard** Improved the Migration Wizard by adding a new capability to create the Migration PR in
  Draft mode.

#### Fixes

* **runners** Fixed incorrect runner banner display on the Workflow table.
* **transversal** Improved GitHub App installation flow by moving autolink logic to the engine.
* **transversal** Fixed an issue where the connection button floated above the navigation and Discord banner.
* **workspace** Enhanced the workspace dashboard with additional KPI metrics.
* **transversal** Improved onboarding by adding migration workflows to the checks process.
* **migration-wizard** Updated pull request message content to enhance the PR flow.
* **migration-wizard** Fixed sync logic to ensure the default branch is fetched immediately.

## 2025-11-17

#### Fixes

* **runners** Added time tooltip to the date column in the Workflow Runs table.
* **workspace** Fixed KPI metrics card showing float percentages and refactored how previous month data is
  displayed.
* **transversal** Improved the design and integration of Get Started actions.
* **billing** Fixed issue where monthly credits were not carried over after workspace deletion.
* **billing** Fixed scheduling issue for payment failed notifications.
* **migration-wizard** Fixed inconsistency in displaying the Migration Wizard button in the runners table
  header.

## 2025-11-10

#### Fixes

* **runners** Fixed issue where “Invalid Value” was displayed under the wrong conditions.
* **billing** Added billing period column and updated date header in the invoices table; void status invoices
  are now excluded.
* **audit-log** Fixed action type and filter on the Audit page to exactly match the dropdown options.
* **billing** Improved number formatting for low amounts in Activities.
* **billing** Fixed Activity chart rendering issues when values are below 0.001.
* **billing** Fixed odd hover behavior on some columns in the Spending Activity chart.
* **runners** Improved animation for the Runner filters menu.
* **runners** Improved GitHub Repositories table data consistency, loading state, and refresh behavior.
* **transversal** Fixed issue where the “Get more credits” link disappeared after being clicked once, so you
  can keep sharing Tenki and earning extra credits ❤️.
* **members** Fixed issue where member email addresses were cut off in the Members table.
* **members** Fixed bug where the invite modal stayed open after removing an invitation.

## 2025-10-31

#### Improvements

* **transversal** Improved design system implementations across multiple app components, including
  notifications, table footers, account cards, role details modals, and uptime status hover interactions.

#### Fixes

* **billing** Updated incoming payment workflow for better reliability.
* **migration-wizard** Updated the pull request message in the Migration Wizard to provide more detailed
  explanations.
* **transversal** Optimized runner installation and performed type cleanup for better onboarding experience.
* **project** Assigned new color palette for rotation themes on the User avatar.
* **migration-wizard** Fixed race condition when fetching repositories in the Migration Wizard.
* **members** Fixed a minor issue with the actions dropdown list in the Invitations table.
* **migration-wizard** Fixed flickering loading state in the Migration Wizard.
* **runners** Fixed bug showing invalid runners offering error in the Workflow Runs table.

## 2025-10-24

#### Improvements

* **billing** We’ve introduced a minimum billing threshold of $2. If your balance is below this amount, it
  will roll over to the next billing cycle until the total exceeds the threshold.
* **notifications** We’ve added a new notification type: Announcements, which will be used to share major
  updates, maintenance notices, and other important information.

#### Fixes

* **transversal** Fixed an issue in the Tenki GitHub App installation flow where approval requests from
  GitHub were not being processed correctly.
* **runners** Resolved layout issues in the List Repositories table and improved data consistency.
* **billing** Fixed data accuracy issues in Spending Activity and Resource Summary sections.
* **transversal** Fixed minor UI component issues across multiple areas, including Workspace, Billing, Audit
  and others sections.
* **billing** Fixed incorrect fetching of routes and street data, rendered on the Invoice handler
  informations.
* **billing** Fixed a bug in the invoice information modal where the action button remained disabled.
* **transversal** Fixed a 404 error that occurred after canceling an installation request and improved the
  cancellation dialog for better clarity.

## 2025-10-17

#### Fixes

* **audit-log** Updated action labels in the Audit Log table.
* **workspace** Fixed column width for email and join date in the Current Members table.
* **transversal** Replaced image on the registration and login pages with a high-quality version.
* **migration-wizard** Improved runner selection experience in the Migration Wizard.
* **migration-wizard** Fixed pre-filled state handling in the Migration Wizard.
* **transversal** Fixed Tenki version display when the sidebar is collapsed.
* **transversal** Updated social proof avatar for improved visual quality.

## 2025-10-10

![Tenki product update](https://tenki.cloud/images/changelog/changelog-10-10.webp)

#### Improvements

* **runners**
  Added invalid label indicator: GitHub runners using unsupported Tenki labels now display an indicator, helping you
  quickly identify and fix configuration issues.
* **transversal**
  Improved Onboarding. You can now pause the onboarding process and resume it anytime from anywhere in the application.
* **transversal** Updated the registration and login design to display helpful insights on the right panel.

#### Fixes

* **transversal** Fixed an issue where opening multiple platform tabs could lead to a 404 error.
* **migration-wizard** Fixed branch dropdown state handling in the Migration Wizard.
* **transversal** Fixed race condition causing layout cache invalidation issues.
* **audit-log** Updated breadcrumbs and fixed labels in the Audit Log table.
* **migration-wizard** Updated the Migration Wizard to automatically prefill the repository name and branch
  when data is available.
* **transversal** Updated styling of the displayed Tenki version in the sidebar.
* **audit-log** Updated Audit Log table design and responsiveness for improved clarity.
* **runners** Reviewed and adjusted avatar size in the Events column of the Workflow Runs table.
* **billing** Removed auto-focus from the Edit Payment modal when redirected.
* **projects** Fixed issue where deleting a project did not redirect to the Workspace dashboard.
* **runners** Updated pagination reset behavior when changing the runner source filter to ensure correct
  results.

## 2025-09-26

#### Fixes

* **billing**
  Fixed street address recommendations in the invoice information modal
* **runners**
  Updated cancel workflow state handling for improved accuracy
* **runners**
  Added filter for runner source (All, Tenki, and non-Tenki)
* **billing**
  Fixed sorting issue in the resource summary usage column
* **transversal**
  Added new error pages for 404, invitation errors, and dashboard errors
* **runners**
  Pre-selected autoscale runners by default in the Migration Wizard
* **transversal**
  Disabled removal of “Get more credits” links after clicking
* **billing**
  Fixed float number formatting on the activity spending chart tick labels

## 2025-09-19

![NotificationRunnerRelease](https://tenki.cloud/images/changelog/changelog-9-19.webp)

#### Improvements

* **transversal**
  Pipelines are now faster than ever! You can now manage caching directly from your Workspace Settings. Caching is
  enabled by default to boost the speed and performance of your workflows, ensuring smoother runs out of the box.

#### Fixes

* **migration-wizard** Enhanced loading states for repositories and branch dropdowns in the Migration Wizard.
* **billing** Added a “Pay Invoice” button to the invoices table.
* **projects** Removed project descriptions from the dashboard.
* **billing** Updated invoices card and table to better highlight free credit usage.

## 2025-09-10

***

#### Fixes

* **billing** Fixed bugs in the invoices table related to date selection and table responsiveness.
* **transversal** Improved mobile layout of the onboarding workflow for a smoother experience.
* **migration-wizard** Resolved responsiveness issue in the Migration Wizard where job names would overlap.
* **project** Fixed delay when renaming projects in the dashboard.
* **runners** Improved responsiveness of the “Re-run all jobs” modal.
* **transversal** Improved suggested actions in the Get Started component.
* **project** Fixed visual glitch when toggling projects in the Project Spending card.
* **billing** Resolved infinite loading state for the payment method.
* **workspace** Fixed Members KPI not displaying correctly in the Workspace Dashboard.
* **billing** Improved copy in the invoice table to better reflect how free credits are used.
* **transversal** Improved audit log export by adding more detailed information.
* **billing** Added Tenki version display to the auth page and dashboard sidebar.
* **billing** Fixed issue with invoice amount showing incorrect decimal places.

## 2025-09-02

***

#### Improvements

* **migration-wizard**
  Released a new version of the Migration Wizard focused on simplifying the onboarding and migration experience by
  removing unnecessary filters and options for a cleaner, faster flow.
* **transversal**
  Improved Notifications and Runners Sheet for better mobile experience.

#### Fixes

* **settings** Fixed mobile layout issues for appearance and notifications in account settings.
* **transversal** Updated account initialization to display the Tenki logo.
* **runners** Fixed table row hover background styling.
* **workspace** Fixed dashboard layout cutoff and scrolling issues.
* **transversal** Added clear function to date range picker.
* **transversal** Fixed “Enable more repositories” access link button.
* **migration-wizard** Fixed mobile responsiveness issues in the migration wizard.
* **transversal** Added empty state UI for “Skip Add Repo” step during registration.
* **transversal** Improved Blue Radio component sizing.

## 2025-08-22

***

#### Improvements

* **migration-wizard**
  Improved the Migration Wizard modal with filtering and selection options to help large teams manage workflow migration
  more easily.

#### Fixes

* **migration-wizard**
  Resolved by removing scroll view from workflow jobs in the migration wizard.
* **workspace**
  Fixed is-suspended check that was preventing users from creating a workspace.
* **transversal**
  Resolved by reverting onboarding container changes to improve responsiveness.
* **billing**
  Resolved by embedding font in the download SVG for spending activity.
* **transversal**
  Fixed responsive issue with the select member dropdown.
* **transversal**
  Resolved by adding “Resend Code” option in password recovery.
* **workspace**
  Resolved 404 issues by redirecting to dashboard when there’s an active session.
* **billing**
  Resolved glitch in project spending graph by using keepPreviousData.
* **workspace**
  Fixed issue where deleting a workspace redirected to a 404 page.

## 2025-08-15

![NotificationRunnerRelease](https://tenki.cloud/images/changelog/changelog-8-15.webp)

***

#### Improvements

* **notification**
  Tenki now sends notifications for Runner activity, so you’ll get alerted when jobs start, fail, or complete.
* **settings**
  We’ve introduced a new onboarding workflow, no more guessing where to click; everything you need now appears in a
  single, clear modal right after registration.
* **transversal**
  You can now connect Public Repositories to your Tenki Projects, making it easy to use Tenki with open-source code.

#### Fixes

* **project**
  Fixed invalidation issue after updating a project.
* **workspace**
  Fixed KPI Card calculations, failure rate, total jobs, and dashboard list metrics now display correctly.
* **workspace**
  Added tooltips on KPI card to help with clarity.
* **runners**
  Fixed offering offering list order in the View Runners sidebar.
* **runners**
  Fixed repository sync workflow failing in some specific use-cases.
* **billing**
  Fixed issue with project spending graph not updating when switching projects.
* **billing**
  Updated KPI logic on the project runners page to ensure total jobs are counted accurately.

## 2025-08-08

***

#### Improvements

* **settings**
  Improved Profile page layout to align with new features and updated navigation.

#### Fixes

* **transversal**
  Fixed various UI inconsistencies across the app and specifically the project page, including breadcrumb spacing,
  sidebar tab radius, icon alignment, and button styles.
* **transversal**
  Resolved layout and interaction issues in the workflow runs and GitHub repositories tables, enhancing label
  visibility, row borders, spacing, sorting, and empty states.
* **transversal**
  Fixed all dialogs to use ghost-style buttons, consistent close icons, and properly sized layouts.
* **transversal**
  Fixed visual bugs in the Notifications view, including misaligned tabs, incorrect text sizing, and flipped icons.
* **transversal**
  Fixed timestamp display issue in the table by ensuring dates are shown in local time instead of UTC.
* **billing**
  Resolved a display issue in the Invoices table to ensure all invoices from the current year are shown correctly.
* **billing**
  Fixed display and unit inconsistencies for Usage and Cost values in the Activity table.

## 2025-08-01

![ActivityPageRelease](https://tenki.cloud/images/changelog/changelog-8-1.webp)

***

#### Improvements

* **billing**
  Introduced a new Billing & Activity page for better visibility into usage and account activity.
* **migration-wizard**
  Our migration tool now supports matrix parameters for the runs-on value, making it even easier to migrate to Tenki.

#### Fixes

* **migration-wizard**
  Fixed behavior inconsistencies and improved the copy in the Migration Wizard to ensure only one wizard is shown per
  workflow.
* **runners**
  Fixed an issue where the "extend row" option was not functioning correctly.
* **workspace**
  Resolved an issue where repositories could not be added to a project.
* **workspace**
  Added tooltips to workspace parameters that are not user-editable.
* **transversal**
  Added redirection to the main website when clicking the Tenki logo from the Login and Registration pages.
* **settings**
  Fixed issues affecting the Profile Avatar workflow.
* **transversal**
  Improved the content and formatting of the welcome email.

## 2025-07-25

***

#### Improvements

* **migration-wizard**
  Introduced the ability to change the base branch for greater flexibility during migration.
* **transversal**
  Updated the Usage component to display current balance and credits, enhancing clarity and expense monitoring.
* **workspace**
  Updated the Project table in Workspace Dashboard to enhance distinction and improve clarity.
* **transversal**
  Enhanced mobile responsiveness across the entire application and all pages.

#### Fixes

* **runners**
  Fixed an issue where the projects list remained visible after workspace deletion until manually refreshed.
* **transversal**
  Fixed missing illustrations in empty state views.
* **settings**
  Fixed incorrect table header height in the invite screen while loading.
* **transversal**
  Resolved various bugs and design inconsistencies in the onboarding process.
* **transversal**
  Fixed side navigation and scrollbar-related issues.
* **runners**
  Updated the copy for the Organization component and improved the "Add Repositories" dialog.
* **runners**
  Fixed scroll issues when switching between workspaces and projects.
* **transversal**
  Removed the code verification step during GitHub account registration.
* **settings**
  Added an error message when connecting a GitHub account that's already linked to another identity.

## 2025-07-18

***

#### Improvements

* **runners**
  Improved the GitHub Organization component to display permission details more clearly and enhance overall clarity.

#### Fixes

* **migration-wizard**
  Fixed an issue where the Workflow Migration Wizard appeared even when already using Tenki Runners.
* **transversal**
  Resolved an issue with GitHub sign-in by removing the unnecessary code verification step.
* **transversal**
  Fixed a mobile display bug affecting the CTA component on the website.
* **transversal**
  Resolved branding inconsistencies on the Tenki landing page related to GitHub and Tenki logo usage.
* **transversal**
  Fixed the `expires_at` error caused by a missing required property.
* **migration-wizard**
  Updated the Runners UI V2 to make the Migration Wizard the default option.
* **transversal**
  Refined the copy for table record info to be clearer and more consistent across contexts.
* **runners**
  Fixed an issue where re-run jobs were showing an inaccurate state.
* **transversal**
  Fixed inaccuracies in the Forgot Password workflow.
* **transversal**
  Fixed a bug in the GitHub Repositories table where the total count displayed was inaccurate.

## 2025-07-11

***

#### Improvements

* **transversal**
  Refined the Usage component to improve clarity and usability.
* **transversal**
  Introduced an improved Get Started component to better guide users through their next steps.
* **transversal**
  Added a universal fallback loader across all pages to enhance perceived performance and ensure smoother loading
  experiences throughout the application.

#### Fixes

* **projects**
  Fixed an issue where the project list would still appear after deleting a workspace until a manual refresh.
* **settings**
  Resolved banner responsiveness issues in the Runner settings.
* **migration-wizard**
  Fixed a bug in the Migration Wizard that prevented existing workflows from loading in certain scenarios.
* **transversal**
  Fixed a scroll issue when switching between workspaces and projects.
* **projects**
  Fixed missing illustration in the projects table.
* **projects**
  Fixed typography and responsiveness issues in the "See Roles and Invitations" table.
* **runners**
  Fixed a bug where `workflow_job` failed when the app was suspended.
* **settings**
  Resolved an issue where the Settings component wouldn't re-render after linking 2FA until a manual refresh.
* **settings**
  Fixed missing error messaging when attempting to connect an already-linked GitHub account.

## 2025-07-04

![LoginGithub](https://tenki.cloud/images/changelog/changelog-6-13.webp)

***

#### Improvements

* **transversal**
  Introduced the ability to register and sign in using your GitHub account for a faster onboarding experience.
* **settings**
  Launched new Login Methods feature, allowing users to link multiple login options including email/password and GitHub
  to a single account.

#### Fixes

* **transversal**
  Fixed a mobile layout issue affecting the CTA component.
* **transversal**
  Implemented a new autoscaling section on the website for improved visibility.
* **project**
  Refined the color palette used for projects to enhance clarity on the Billing Activity page.
* **workspace**
  Added an “Insufficient Permissions” tooltip to better guide user actions.
* **workspace**
  Fixed an issue that occurred when leaving the only accessible workspace, which previously blocked workspace creation.
* **workspace**
  Fixed a pagination bug in the GitHub Repositories table that caused incomplete data display.
* **settings**
  Added a visible email field in the Profile settings page and on avatar hover for easier account identification.

## 2025-06-27

***

#### Improvements

* **runners**
  Introduced a refresh capability to the table, allowing users to update runner data on demand for improved visibility
  and real-time accuracy.
* **settings**
  Enhanced the user profile experience with an updated profile image upload dialog, offering a cleaner interface and
  better feedback during uploads.

#### Fixes

* **migration-wizard**
  Fixed a bug that occurred when switching from one repository to another.
* **workspace**
  Fixed an issue where workspaces with long names weren’t being entered.
* **workspace**
  Fixed a bug where deleting members took excessively long.
* **workspace**
  Fixed a typo on the Edit Project modal.
* **runners**
  Fixed an issue by adding tags for dynamic resources in the Autoscale offering.
* **transversal**
  Fixed a scrollbar issue where it remained visible even when the user wasn’t scrolling.
* **transversal**
  Fixed table empty states with updated titles, animations, and improved links.

## 2025-06-20

![Ubuntu2404](https://tenki.cloud/images/changelog/changelog-6-20.webp)

***

#### Improvements

* **runners**
  The default runner image has been updated to Ubuntu 24.04, bringing enhanced security, access to newer packages, and
  improved compatibility with modern development environments.
* **members**
  Improved the Roles table implementation by adding collapsible sections, enhancing readability and making it easier for
  users to navigate and understand role details.

#### Fixes

* **notification**
  Fixed the notification success message to clearly indicate which setting was changed and whether it was enabled or
  disabled (checked/unchecked).
* **transversal**
  Fixed a bug causing incorrect padding on the Resend button during the onboarding flow.
* **runners**
  Fixed a bug where the Runner offering text was getting cut off in the interface.
* **transversal**
  Fixed an issue with the resend email code and updated the copy for better clarity and consistency.
* **transversal**
  Fixed a bug where the Workspace List was not responsive on certain screen sizes.
* **runners**
  Fixed an issue with the Repository filter where searching for a value resulted in duplicated entries in the results.
* **runners**
  Fixed a bug that caused a 404 error when accessing a Workspace Dashboard immediately after accepting an invitation.
* **transversal**
  Fixed the formatting of the onboarding email to properly handle and display long email addresses.

## 2025-06-13

***

#### Improvements

* **transversal**
  Released a new version of the Tenki Website with improved responsiveness and a stronger emphasis on the unique
  benefits of switching to Tenki.
* **transversal**
  Avatars now feature a more vibrant default color palette. Also remember that we still have support for custom image
  uploads, including animated .gif files!.

#### Fixes

* **workspace** Improved visibility of Workspace name in the sidebar on mobile and tablet devices to enhance
  navigation clarity.
* **transversal**
  Fixed responsiveness issues in the onboarding flow when handling long email addresses.
* **transversal**
  Improved onboarding by requiring users to complete verification before accessing the dashboard.
* **workspace**
  Fixed a regression where a default workspace was still being created after a user was invited to an existing
  Workspace.

## 2025-06-06

***

#### Improvements

* **transversal**
  Fast Registration 💨 We’ve streamlined the sign-up process by removing non-essential steps making onboarding faster,
  smoother, and more efficient than ever.
* **workspace**
  Improved Workspace handling: users removed from their only workspace are now properly redirected to the workspace
  creation page reducing confusion and ensuring a clear next step.

#### Fixes

* **transversal**
  Fixed responsiveness issues in the filters section of the Notification sidebar to ensure a smoother experience across
  all screen sizes.
* **workspace**
  Fixed a bug that allowed creation of duplicate workspace names.
* **workspace**
  Fixed a bug where, in some cases, users did not receive workspace invitation emails.
* **workspace**
  Fixed a bug where removed members could still see the workspace or project in their dropdown menus.
* **workspace**
  Fixed a bug that caused an error when re-inviting previously removed members, incorrectly stating they were still part
  of the workspace.

## 2025-05-30

***

### Meet the Runner Autoscale Offering

![AutoscaleOffering](https://tenki.cloud/images/changelog/changelog-5-30.webp)

#### Improvements

* **runners**
  No more guessing resources or paying for unused compute. Switch to `tenki-standard-autoscale` it automatically adapts
  to your workflow’s size and needs. Set it once, and let it scale forever ❤️
* **runners**
  Enhanced the View Runners sidebar and the Migration Wizard to improve segmentation and prominently highlight our new
  Autoscale Runner offering as the recommended default.
* **transversal**
  Added a new error page when attempting to accept an invite using a non-invited account.
* **project**
  Enhanced the Members column in the project table on the Workspace page to improve clarity and distinguishability.

#### Fixes

* **runners**
  Improved loading performance of the Runners page.
* **runners** Adjusted the skeleton loader height in the job list to match the final row height without
  having a initial response that will be updated few seconds after.
* **workspace**
  Fixed a bug where project names couldn’t be edited from Workspace Settings.
* **project**
  Corrected a typo in the Create Project dialog box.
* **transversal**
  Fixed an issue where the header wasn’t rendered correctly during scrolling.
* **workspace**
  Resolved a bug where deleted members could still access resources in certain cases.

## 2025-05-23

***

#### Improvements

* **migration-wizard** We've made the Migration Wizard more powerful you can now also migrate your jobs to
  Tenki Runners directly from the Runs list, making the process faster and more intuitive.
* **transversal**
  We've made it easier for invited users who aren’t already on Tenki by adding a banner that clearly informs them which
  Workspace they’re joining when registering.

#### Fixes

* **runners** Resolved an issue where the increase/decrease icon and background were not rendering correctly
  on runner cards.
* **migration-wizard** Improved the responsiveness of the Migration Wizard modal across various screen sizes.
* **runners** Refined the layout of the workflow runs table to improve information hierarchy and help users
  find key details more easily.
* **migration-wizard** Fixed an issue that allowed generating a PR without changing the runner, which offered
  no real benefit.
* **runners** Fixed a bug where the status of some jobs wasn’t updating as expected.
* **workspace** Fixed an issue where some users couldn’t leave the workspace they were invited to.
* **transversal** Fixed a bug causing the navigation bar to occasionally fail to render properly.

## 2025-05-16

***

![MembersPage](https://tenki.cloud/images/changelog/changelog-5-16.webp)

#### Improvements

* **transversal**
  We’ve just launched our custom Notifications system 🔔🔕. Stay on top of important updates in your Workspace get
  notified when someone accepts your invite, leaves your workspace, and more. We’re continuing to expand notification
  coverage, so you’ll never miss a critical change.
* **runners**
  Enhanced information hierarchy in the Workflow Runs table to better distinguish between Runs and Jobs.
* **runners**
  To better align with the most common workflows while maintaining a great user experience, we’ve reviewed and updated
  our runner offerings. The new lineup includes: - tenki-standard-small-2c-4g - tenki-standard-medium-4c-8g -
  tenki-standard-large-8c-16g - tenki-standard-large-plus-16c-32g

#### Fixes

* **runners**
  Improved the Runners KPI cards with clearer colors, correct arrow directions and cleaner percentages.
* **transversal** Fixed a bug affecting the theme on the Documentation website.
* **workspace** Fixed a bug where Standard members were incorrectly allowed to delete Workspaces and
  Projects.

## 2025-05-09

***

#### Improvements

* **repository**
  Enhanced GitHub Integration for Runners. It’s now easier to connect your GitHub Organization with a clearer interface,
  and you can now view the Tenki Workspace that are already linked to a GitHub Organization, as we allow for only unique
  connections.
* **repository**
  In the Add Repository dialog, we’ve refined the layout and enriched the displayed information to help you more easily
  identify which repositories to add to your Tenki project.
* **repository**
  Improved user experience in the Connect Projects to Repository dialog by optimizing how the repositories list is
  rendered during loading.
* **migration-wizard**
  Now hiding the Migration Wizard button when no GitHub Organization or Initialization is connected.

#### Fixes

* **repository**
  Enhanced the UI state when connecting a GitHub Organization that has no private repositories.
* **runners**
  Fixed an issue where some job statuses were not updating correctly.
* **runners**
  Resolved a bug causing some runs to constantly reorder in the Workflow Runs table.
* **transversal**
  Fixed an issue where the navigation bar background color would sometimes disappear while scrolling.
* **transversal** Fixed missing sorting options in the Table Component.

## 2025-05-02

***

### Meet the Tenki Migration Wizard: Seamless, One-Click Repository Migration

[Video](https://storage.googleapis.com/tenki-cloud-assets/docs/migration_wizard_demo.mp4)

#### Improvements

* **migration-wizard** Introducing the Tenki Migration Wizard 🎊🧙‍♂️. Your fast, seamless, and stress-free path
  to our Runners is here. This is a guided, step-by-step tool that makes moving to Tenki effortless. **Simply choose the
  repository and select the runner you want and your migration is done in seconds**. It’s all about speed, simplicity,
  and peace of mind.
* **runners** Added a new filter to the `Workflow Runs` table to easily view activity from `Tenki Runners
  Only`. Also improved the layout of existing filter options for better usability.

#### Fixes

* **transversal** Implemented a second-level skeleton loading state across all table components for smoother
  UX.
* **transversal** Added contextual documentation links on various pages to support user onboarding and
  feature comprehension.
* **workspace** Fixed an issue where the project form would render even if no workspace had been created.
* **workspace** Resolved a bug where the dashboard did not auto-refresh after creating a new workspace.
* **repository** Fixed an issue where connected GitHub repositories incorrectly displayed as “initialized”
  until the page was refreshed.

## 2025-04-25

***

![MembersPage](https://tenki.cloud/images/changelog/changelog-4-24.webp)

#### Improvements

* **navigation** We introduced a clearer navigation experience to better distinguish between Workspaces and
  Projects, making it easier to switch between the two.
* **runners** Added key performance indicators on the Runners Activity page for improved tracking and
  monitoring (Total Jobs/ Job Duration (Median)/ Job Duration (P90)/ Failure Rate).
* **runners** You can now search repositories directly in the `Add Repository` dialog, speeding up the
  selection process.
* **runners** Added `Last 30 minutes` and `Last 1 hour` options to the time range filter for more flexible
  monitoring.

#### Fixes

* **navigation** Made the top navigation bar sticky for better usability across pages.
* **settings** Corrected a bug affecting Full Name display in user profile settings.
* **settings** Fixed an issue where a broken image appeared as the avatar on first login.
* **runners** Fixed a bug in the Workflow Runs date picker where date inputs didn’t behave as expected.
* **members** Resolved an issue where admins couldn’t access the Members page after being promoted.
* **runners** Enhanced the responsiveness of the Invitation dialog box when the `Partial` Access Scope option
  is selected.

## 2025-04-16

***

#### Improvements

* **workspace** Enhanced the tooltip in the Project Members column to display all members at a glance for
  quicker visibility.
* **repository** The "Configure" option is now hidden for users who aren’t repo owners. A tooltip has been
  added to clarify why it’s unavailable.
* **login** Added an option to "Log in instead" during onboarding for existing users.
* **navigation** Workspace and Project dropdowns are now sorted alphabetically by default to make it easier
  to find the right one.
* **members** Improved the “Access Denied” state with clearer messaging. Refer to the Access Table for a
  breakdown of role-based permissions.

#### Fixes

* **project** Fixed an issue where users were redirected to the wrong page after deleting a project.
* **workspace** Resolved a bug preventing Admins from sending workspace invitations.
* **runners** Fixed pagination and responsiveness issues on the Runners table.

## 2025-04-14

***

#### Introducing Tenki Runners - a cheaper alternative to Github Runners

[Video](https://storage.googleapis.com/tenki-cloud-assets/docs/2025-05-14-tenki-tour.mp4)

Today, we are revealing the result of many weeks of work building our first capability for Tenki: **Runners**

**Runners**: Introducing Tenki’s first core capability our high-performance, cost-effective alternative to GitHub Runners. Built for speed and usability, with a streamlined onboarding experience and a redesigned dashboard that makes filtering jobs and workflows simple and intuitive.

**Workspace & Projects**: Structure your environment your way with two levels of organization. Workspaces provide a global view, while Projects allow for more granular management and separation.

**Members Management**: You can now invite and manage users based on scope (Full Workspace or Project-specific) and assign roles as **Admin** or **Standard**, giving you more control over access and collaboration.

# Editorial & Corrections Policy (https://tenki.cloud/docs/editorial-policy)

Last Updated: April 28, 2026


This Editorial & Corrections Policy explains how content is created, reviewed, and corrected on Tenki properties, including [tenki.cloud](https://tenki.cloud), our [documentation](https://tenki.cloud/docs.md), our [blog](https://tenki.cloud/blog), and our [changelog](https://tenki.cloud/docs/changelog.md). It applies to written guides, technical references, benchmarks, comparison pages, marketing copy, and any artifact published under the Tenki brand.

We publish this policy because depth and accuracy matter to the engineers who rely on our docs in production. If you spot an error, see the [Reporting an error](#reporting-an-error) section below, we will respond.

**Maintained by:** Tenki Cloud content team, with the Product lead acting as editor-in-chief. Questions, corrections, or policy clarifications go to [hello@tenki.cloud](mailto:hello@tenki.cloud).

***

## 1. Editorial Standards

We hold all Tenki content to four standards:

* **Accurate.** Technical claims, numbers, pricing, and benchmarks are verified against primary sources at time of publication. Where we cite third-party data, we link to the source.
* **Current.** Pages that reference pricing, performance, product behavior, or compliance status are reviewed at least quarterly, and immediately when the underlying product or contract changes.
* **Independent.** Content reflects Tenki's independent assessment. We do not accept payment, gifts, or commercial incentives in exchange for editorial coverage on this site.
* **Transparent.** We disclose authorship, methodology, and material limitations. Where a claim cannot be independently verified by a reader, we say so.

## 2. Who Reviews Content Before Publication

Every piece of long-form content goes through a documented review chain before it ships:

* **Author.** Drafted by a Tenki engineer, product manager, or technical writer with hands-on experience in the subject matter. Drafts include sources for any non-obvious claim.
* **Technical reviewer.** A second Tenki engineer or domain owner reviews for technical accuracy, reproduces benchmarks where applicable, and confirms that command snippets, APIs, and configuration examples work against the current Tenki product.
* **Editor.** Reviews structure, clarity, terminology, and adherence to the [Brand Guidelines](https://tenki.cloud/docs/brand-guidelines.md) and [Branding](https://tenki.cloud/docs/branding.md) pages. The editor is responsible for removing unsupported superlatives and ensuring that comparisons are sourced.
* **Compliance / legal review.** Pages that touch security, privacy, compliance posture, contractual commitments, or regulated claims (for example SOC 2, ISO 27001, GDPR, SLA language) get a final pass from the team responsible for those programs before they go live.

For the public [changelog](https://tenki.cloud/docs/changelog.md), entries are sourced directly from merged pull requests, edited by the release manager, and reviewed by the engineer who shipped the change before the entry is published.

## 3. AI-Assisted Authoring

We use AI tools to draft, summarize, and edit content. AI is treated as a research and drafting assistant, never as a publisher. Every AI-assisted draft is reviewed by a named human author, fact-checked against primary sources, and signed off by a technical reviewer using the chain in [Section 2](#2-who-reviews-content-before-publication). We do not publish unedited model output as Tenki editorial content.

## 4. Corrections

When we discover or are made aware of an error, we fix it on the same page using the following rules:

* **Fix in place.** The original page is updated with the corrected information rather than republished under a new URL, so external links continue to work.
* **Date-stamped correction note.** Material corrections (factual errors, changed numbers, retracted claims, broken instructions) carry a dated correction note at the top or bottom of the page summarizing what changed and when. Format: `Correction, YYYY-MM-DD: previous text said X; updated to Y.`
* **Last Updated.** Every legal, policy, and reference page carries a `Last Updated` date in the page header. We refresh this date whenever the page changes substantively.
* **Source of truth.** For pricing, performance numbers, and compliance claims, the [Pricing page](https://tenki.cloud/pricing), [Security page](https://tenki.cloud/company/security), and the underlying Order Form / contract are the authoritative sources. If the docs and the source of truth disagree, the source of truth wins and the docs are corrected.
* **Trivial fixes.** Typos, broken links, image swaps, and other non-substantive copy edits are made silently without a correction note.
* **Retractions.** If we determine a piece of content is materially wrong and cannot be salvaged, we will replace the body of the page with a dated retraction note explaining what was wrong, and point readers to the corrected resource.

## 5. Reporting an Error

If you spot a factual, technical, or pricing error on any Tenki page, please tell us. We aim to acknowledge reports within two business days and to publish a correction within five business days of confirming the issue.

* **Email:** [hello@tenki.cloud](mailto:hello@tenki.cloud) with the page URL, the specific text or number you believe is wrong, and, if you can, a link to the source that supports the correction.
* **Documentation issues:** if it is faster, you can also flag the issue in our community [Discord](https://discord.gg/qNFaWrR6um) `#docs` channel.
* **Security issues:** vulnerabilities and security-impacting errors should follow our [responsible disclosure process](/company/security#operations--disclosure) instead, not the editorial channel.

We credit reporters by name on request once the correction has shipped.

## 6. Sponsorship, Affiliate, and Conflict-of-Interest Disclosure

Tenki content on this site is **not sponsored, paid, or affiliate-driven**. Specifically:

* We do not accept payment, free product, or other commercial incentives in exchange for inclusion in our docs, blog, or comparison pages.
* We do not run paid placements as editorial content. Any paid promotion is clearly labeled as advertising.
* We do not earn affiliate commissions on outbound links to third-party tools, vendors, or cloud providers from this site.
* When we reference our parent company [Luxor Technology](https://luxor.tech/), we disclose the corporate relationship in line.
* When we reference customers, partners, or design partners by name, we do so with their permission. We do not exchange editorial coverage for commercial terms.

If this changes in the future, for example if we add affiliate links on a comparison page, or run a sponsored content slot, we will update this policy and clearly label affected content.

## 7. User-Generated Content and Third-Party Quotes

Customer testimonials, social-proof quotes, and case-study content are published only with the customer's written permission. We do not edit quotes in a way that changes their meaning. Statistics and benchmarks attributed to third parties link to the original publication. Screenshots and product names belonging to other companies are used under nominative fair use solely to describe interoperability or comparison context.

## 8. Changes to This Policy

We may update this policy as our publishing practices evolve. Material changes will be summarized at the top of this page and reflected in the `Last Updated` date.

## 9. Contact

Questions about this policy, our editorial process, or a specific piece of content can be sent to [hello@tenki.cloud](mailto:hello@tenki.cloud).

# Tenki Cloud Documentation (https://tenki.cloud/docs)

Complete Tenki documentation for GitHub Actions alternatives. Fast setup, 2-click migration, and up to 60% cheaper CI/CD runners.

# What is Tenki?

Tenki is infrastructure for AI agents and the teams working alongside them. As agents write more of your code, your team needs a safe place to run it and a way to trust what comes back. Tenki gives you isolated Linux VMs where agents execute code, fast runners for the CI that checks it, and automated review that flags only what blocks a merge.

## Building blocks

* [**Sandbox**](https://tenki.cloud/docs/sandbox/quickstart.md) gives AI agents disposable full Linux VMs to write, run, and ship code in isolation.
* [**Runners**](https://tenki.cloud/docs/runners/quickstart.md) run your jobs on dedicated machines that finish faster and cost less than GitHub-hosted runners.
* [**Code Reviewer**](https://tenki.cloud/docs/start-code-review.md) analyzes your PRs and flags only what blocks a merge.

Use each on its own, or connect all three into one flow.

- [Sandbox - Quickstart](https://tenki.cloud/docs/sandbox/quickstart.md): Spin up disposable Linux VMs for AI agents, drivable from the CLI, TypeScript, Go, or Python SDK.

- [Runners - Quickstart](https://tenki.cloud/docs/runners/quickstart.md): Set up Tenki Runners and run your first CI job on dedicated infrastructure in under 2 minutes.

- [Code Reviewer - Quickstart](https://tenki.cloud/docs/start-code-review.md): Set up Tenki Code Reviewer and get AI-powered PR analysis in minutes.

- [Pricing](https://tenki.cloud/docs/pricing.md): See pricing for Tenki Sandbox, Runners, and Code Reviewer, and how the billing cycle works.

- [Security & Isolation](https://tenki.cloud/docs/trust/security.md): Ephemeral per-job VMs, isolation model, SOC 2 Type II program via parent company Luxor.

- [Socials](https://tenki.cloud/docs/tenki-socials.md): Join our community to connect with the Tenki team and other developers, and hear what's new.

# Pricing (https://tenki.cloud/docs/pricing)

Tenki pricing plans with Starter and Team tiers, per-unit feature rates, and enterprise options for GitHub Actions runners and code reviews.

Tenki offers two workspace plans, **Starter** and **Team**, plus an **Enterprise** option for larger organizations. All plans include access to Tenki Runners and Tenki Code Reviewer, billed on a usage basis beyond your monthly credits.

## Plans

***

### Starter, $0/month

The Starter plan is free and includes monthly credits to get started with no upfront payment.

| Feature                 | Included                 |
| ----------------------- | ------------------------ |
| Monthly credits         | $10                      |
| Workspace members       | Up to 5                  |
| Code Reviewer seats     | Up to 5                  |
| Active Sandbox sessions | Up to 5                  |
| Sandbox storage         | Up to 100 GiB            |
| Concurrent Runner jobs  | Up to 5                  |
| Runner size             | Up to 4 cores / 8 GB RAM |
| Runner cache            | Up to 5 GB               |
| Premium Runners         | Not available            |
| Priority Support        | Not available            |

Usage beyond the $10 monthly credits is billed at the feature rates below.

### Team, $200/month (billed yearly)

$250/month with monthly billing. Includes higher limits, premium infrastructure, and priority support.

| Feature                 | Included                             |
| ----------------------- | ------------------------------------ |
| Monthly credits         | $100                                 |
| Workspace members       | Up to 50                             |
| Code Reviewer seats     | Up to 50                             |
| Active Sandbox sessions | Up to 25                             |
| Sandbox storage         | Up to 500 GiB                        |
| Concurrent Runner jobs  | Up to 50                             |
| Runner size             | Up to 64 cores / 256 GB RAM          |
| Runner cache            | Up to 10 GB                          |
| Premium Runners         | Included (high-speed infrastructure) |
| Priority Support        | Included                             |

Usage beyond the $100 monthly credits is billed at the feature rates below.

### Enterprise, Custom

For organizations that need more than Team offers. Contact us to build a plan that fits your needs.

* Self-hosting option
* Multi-org support
* SLA support
* Dedicated Slack channel for support
* Custom invoicing and payment terms
* Custom terms of service

## Feature Rates

***

All usage beyond your plan's monthly credits is billed at the following per-unit rates:

| Feature            | Rate                                    |
| ------------------ | --------------------------------------- |
| Code Reviews       | $1.00 per review                        |
| x64 Runners        | $0.002 per core/minute                  |
| macOS Runners      | $0.025 per core/minute                  |
| Extra Runner Cache | $0.20 per GB/month                      |
| Sandbox vCPU       | $0.000014 per second                    |
| Sandbox Memory     | $0.0000045 per GiB/second               |
| Sandbox Storage    | $0.00000003 per GiB/second (5 GiB free) |

# Privacy Policy (https://tenki.cloud/docs/privacy-policy)

Last Updated: July 20, 2026


## 1. Introduction

Tenki Cloud, LLC, a wholly owned subsidiary of Luxor Technology Corporation ("Tenki," "we," "our," or "us") is committed to protecting your privacy. A core element of our mission is our commitment to protect your personal information and to be transparent about the data we collect about you, how it is used, and with whom it is shared.

This Privacy Policy ("Policy") describes our practices for collecting, using, maintaining, protecting, and disclosing your information when you access or use our website ("Website"), applications ("Apps"), and cloud services and related offerings, including our AI-powered code review capability (collectively, the "Service").

**Data controller.** For the purposes of the EU/UK GDPR, the controller of your personal information is Tenki Cloud, LLC, a wholly owned subsidiary of Luxor Technology Corporation, 235 Moore Lane, Suite 120, Billings, MT 59101, USA. Our Data Protection Officer can be reached at [hello@tenki.cloud](mailto:hello@tenki.cloud).

Please read this Policy carefully. By accessing or using our Services, you agree to this Policy. If you do not agree, your choice is not to use our Services. This Policy may change from time to time, your continued use of the Services after changes are posted constitutes your acceptance of those changes.

***

## 2. Information We Collect

We collect only the minimum amount of information needed to provide you with our Services.

### A. Information You Provide Directly

* Name, email address, organization, and billing information when you register or subscribe.
* Account credentials and authentication data. Account credentials and authentication data are treated as Sensitive Personal Information under the CPRA; see Section 9.
* Any information submitted through support requests or correspondence with us.
* Feedback or contributions submitted through our Website or third-party platforms (collectively, "User Contributions"). User Contributions are posted and transmitted at your own risk; we cannot control how others interact with content you share.

### B. Information Collected Automatically

As you interact with our Services, we and our third-party service providers may automatically collect:

* **Usage data** such as pages visited, links clicked, resource consumption, error logs, and interaction statistics.
* **Device and network information** such as IP address, browser type, operating system, and device identifiers.
* **Non-identifying information** such as demographic data, time zone, and publicly available data.

### C. Cookies and Tracking Technologies

Tenki and its partners use cookies and similar technologies to analyze trends, administer the Website, and improve our Services.

* **Cookies:** Small data files placed on your device for record-keeping. We use both persistent and session cookies. You may control cookies at the browser level, though disabling them may limit certain features.
* **Web Beacons:** Small graphics with unique identifiers used to track engagement and content effectiveness.
* **Embedded Scripts:** Code temporarily downloaded onto your device that collects information about your interactions with the Service.

### D. Information Received from Third Parties

We may receive information about you from third parties, including:

* **Code hosting platforms** (GitHub, etc..): We may collect data necessary to integrate with your account, such as access token, user organization, username, and user role. We do not have access to your credentials for these platforms.
* **Payment processors** such as Stripe, which handle payment data on our behalf.

***

## 3. How We Use Your Information

We may use the information we collect to:

1. Provide, maintain, and improve the Service, including creating and managing your account.
2. Perform AI-powered code reviews, provide actionable suggestions, and enhance your development workflow.
3. Authenticate users and manage access to the Service.
4. Process payments and send billing notifications.
5. Respond to inquiries and provide customer support.
6. Communicate with you about the Service and promote products, services, and events offered by Tenki.
7. Tailor content and offers to you within the Service.
8. Comply with legal obligations and enforce our Terms of Service.
9. Detect, prevent, or address fraud, security issues, or other unlawful activity.

***

## 4. Legal Bases for Processing

We rely on the following legal bases to process your information:

* **Contractual Necessity:** To provide you with the Services and perform our contract with you.
* **Legitimate Interests:** To improve and analyze our Service, prevent fraudulent transactions, and maintain security.
* **Consent:** Where indicated in this Policy, including for direct electronic marketing where required by law and for optional data storage under Section 7. You may withdraw consent at any time by contacting us (see Section 14), and you may object to direct marketing at any time.
* **Legal Obligation:** To comply with applicable law, including tax, accounting, and KYC/AML obligations.

***

## 5. Sharing and Disclosure

We do not sell your personal information. We may share your data with third parties only in the following circumstances:

* Service Providers: We use trusted third-party vendors, such as Stripe (for payment processing) and GitHub (for account integrations), to help us deliver the Service. Additional third-party integrations may be added in the future.
* Legal Compliance: If required by law, subpoena, or legal process, we may disclose your information to the appropriate authorities.
* Business Transfers: In connection with a merger, acquisition, or sale of assets, your information may be transferred to another entity.
* **Processors.** Stripe, GitHub, Anthropic, and OpenAI act as our service providers/processors under data processing agreements that restrict their use of personal information to providing services to us. A current list of sub-processors is available on request.

### Service Integrations

To provide the best possible functionality, we integrate with:

* GitHub for code repository access and management.
* OpenAI, Anthropic, or similar to power AI code review functionality.

> ⚠️ **Important:** Neither Tenki nor Anthropic or OpenAI or similar tools will use personal information collected as part of the code review process to train, refine, or otherwise influence AI models. Data is used solely to perform code reviews as requested. This representation does not apply to open-source projects.

### Legal Compliance

We may disclose your information if required by law, subpoena, legal process, or governmental request, or to protect the rights, property, and safety of Tenki, our users, or the public.

### With Your Consent

We may share your information in other ways with your explicit consent.

***

## 6. Do Not Track and Opt-Out Preference Signals

We do not use your personal information for cross-context behavioral advertising, and we do not permit third parties to track our users across other sites for that purpose. Some web browsers offer a Do Not Track ("DNT") preference, and we respect this signal. Where required by the CPRA, we also honor the Global Privacy Control (GPC) and similar opt-out preference signals as a valid request to opt out of sale/sharing.

***

## 7. Data Retention

We retain personal information for as long as necessary to provide the Services, comply with legal obligations, resolve disputes, and enforce our agreements. We may retain anonymized or aggregated data indefinitely. As general guidance: account and profile data are retained for the duration of your account and for 90 days after your account is closed (you may request closure at any time by contacting [hello@tenki.cloud](mailto:hello@tenki.cloud)); billing records are retained for 7 years to meet tax/accounting obligations; support correspondence for 24 months; and vector embeddings until you opt out or request deletion. The criteria we use to determine retention periods include:

* The length of time we have an ongoing relationship with you.
* Legal obligations requiring us to retain records for a set period.
* Our legal position, including for statutes of limitations, litigation, or regulatory investigations.

### Data Storage for Review Improvement

To improve the quality and personalization of code reviews, Tenki stores certain data, primarily vector embeddings, to align future reviews with your preferences. This storage follows security best practices aligned with SOC 2 and GDPR principles. Tenki operates under the SOC 2 Type II program of its parent company Luxor Technology. You may opt out of data storage at any time by contacting us.

***

## 8. Data Security

We implement physical, technical, and organizational measures designed to protect your information against unauthorized access, alteration, disclosure, or destruction. We restrict access to personal information to employees who need it to perform their job functions.

We take care in selecting third-party organizations that may handle personal data on our behalf, reviewing their security posture and data protection policies, and binding them by contractual obligations to ensure confidentiality and security.

No system or electronic data transmission is completely secure. Any transmission of personal data is at your own risk, and you are responsible for maintaining the security of your account credentials. In the event of a personal-data breach, we will notify affected individuals and competent authorities where and as required by applicable law.

***

## 9. Your Rights and Choices

Depending on your jurisdiction, you may have the right to:

* Access or request a copy of the personal information we hold about you.
* Correct or update inaccurate or incomplete data.
* Delete your personal data, subject to our legal and contractual obligations.
* Opt out of marketing emails by following the unsubscribe instructions in those communications. Note that we may still send essential transactional communications.
* **Withdraw consent** at any time where we rely on consent, without affecting prior processing.

You may exercise these rights — including requesting closure of your account and deletion of your data — by contacting us at [hello@tenki.cloud](mailto:hello@tenki.cloud). We will verify your identity before responding and will respond within the timeframes required by applicable law.

### European Residents (GDPR)

Under the General Data Protection Regulation (GDPR), Tenki is a data controller for personal information processed in connection with European residents. In addition to the rights above, you may object to processing, request restriction of processing, or request data portability. Contact us at [hello@tenki.cloud](mailto:hello@tenki.cloud) to exercise these rights.

**Supervisory authority; response time; automated decisions.** You have the right to lodge a complaint with your local data protection supervisory authority. We will respond to rights requests within one month, extendable by two further months for complex requests. We do not make decisions producing legal or similarly significant effects on you based solely on automated processing; our AI code review analyzes code and does not evaluate individuals in that manner.

### California Residents (CCPA, as amended by the CPRA)

**Categories we collect.** In the past 12 months we have collected: identifiers (name, email, account ID, IP address); commercial information (subscription/billing records); internet or network activity (usage and device data); professional/employment and company information (organization, role, from applications); and Sensitive Personal Information (account credentials/log-in information). Sources: you, your use of the Service, and code-hosting/payment providers. Business purposes: those in Section 3. We disclose PI to the categories of third parties in Section 5 (service providers/processors, and legal/business-transfer recipients).

**Sensitive Personal Information.** We use Sensitive Personal Information (account credentials) only to provide the Service, authenticate you, and ensure security and fraud prevention — purposes for which the CPRA does not require a "Limit the Use of My Sensitive Personal Information" option. We do not use or disclose it to infer characteristics.

If you are a California resident, the California Consumer Privacy Act (CCPA) provides you with additional rights, including:

* The right to know what personal information we have collected and how we have used and disclosed it in the prior 12-month period.
* The right to request deletion of your personal information.
* The right to correct inaccurate personal information.
* The right to be free from discrimination for exercising your privacy rights.
* The right to opt out of the sale or sharing of your personal information. Tenki does not sell personal information, nor do we share it with third parties for cross-context behavioral advertising, so no "Do Not Sell or Share" action is required; if this changes, we will provide that link and honor opt-out preference signals.
* **The right to use an authorized agent** to submit requests on your behalf, subject to our verification of the agent's authority.

To exercise your CCPA rights, contact us at [hello@tenki.cloud](mailto:hello@tenki.cloud).

***

## 10. International Users

Tenki is based in the United States. Our servers are located in the U.S., and your personal information may be transferred to, stored, and processed in the U.S. or other countries where we operate.

Where we transfer personal information out of the EEA, UK, or Switzerland, we rely on appropriate safeguards under applicable law — principally the European Commission's Standard Contractual Clauses (and the UK International Data Transfer Addendum) — or another lawful transfer mechanism. You may request a copy of the safeguards we use by contacting [hello@tenki.cloud](mailto:hello@tenki.cloud).

***

## 11. Third-Party Websites and Links

Our Services may contain links to third-party websites or platforms. We do not control these platforms and are not responsible for their content, privacy policies, or use of your information. We encourage you to review the privacy policies of any third-party sites you visit.

***

## 12. Children's Privacy

The Service is intended for users 13 and older. For some of our enterprise and cloud offerings, the Service is intended only for users 18 and older. In the EEA/UK, where consent is the basis for an online service, the minimum age is 16 (or the lower age set by your member state, between 13 and 16). We do not knowingly collect personal information from anyone under these applicable age thresholds. If we become aware that we have inadvertently collected such information, we will take steps to delete it promptly. If you believe we have collected information from a child under the applicable age, please contact us immediately.

***

## 13. Changes to This Policy

We may update this Privacy Policy from time to time. Material changes will be indicated by updating the "Last Updated" date at the top of this Policy. We may also notify you by email at our discretion. Your continued use of the Services after any changes constitutes your acceptance of the updated Policy.

***

## 14. Contact Us

A Data Protection Officer has been appointed and can be reached with any questions or concerns regarding this Privacy Policy or your personal data at [hello@tenki.cloud](mailto:hello@tenki.cloud), or by mail at Tenki Cloud, LLC, 235 Moore Lane, Suite 120, Billings, MT 59101, USA.

| Contact Type            | Email                                         |
| ----------------------- | --------------------------------------------- |
| General Support         | [hello@tenki.cloud](mailto:hello@tenki.cloud) |
| Data Protection Officer | [hello@tenki.cloud](mailto:hello@tenki.cloud) |

# Get Started with Tenki Code Reviewer (https://tenki.cloud/docs/start-code-review)

Set up Tenki Code Reviewer in minutes. Install its GitHub App and get high-signal pull-request reviews.

**Step 1:**
## Create your Tenki Account

Open the [Tenki registration page](https://app.tenki.cloud/auth/registration/) and register with email and password or GitHub.

![Tenki registration page with email and GitHub sign-up options](https://tenki.cloud/images/get-started/account-creation.png)

**Step 2:**
## Access the Tenki Code Reviewer panel

Open the [Tenki dashboard](https://app.tenki.cloud), choose your workspace and project, then select **Code Reviewer**.

![Tenki dashboard with Code Reviewer selected for a project](https://tenki.cloud/images/get-started/tcr-step1.png)

**Step 3:**
## Install the Tenki Reviewer GitHub App

From the Code Reviewer panel, start the GitHub connection and install the separate Tenki Reviewer GitHub App for your organization.

![Code Reviewer setup screen prompting installation of the Reviewer GitHub App](https://tenki.cloud/images/get-started/tcr-step2.png)

![GitHub page for choosing the organization for the Tenki Reviewer App](https://tenki.cloud/images/get-started/tcr-step3.png)

Choose the repositories the Reviewer can access, then select **Install & Authorize**:

![GitHub permissions screen for installing and authorizing the Tenki Reviewer App](https://tenki.cloud/images/get-started/tcr-step4.png)

**Step 4:**
## Create Your First PR Review

Perfect, you’re all set! 🎊. There are now two ways to trigger the Tenki Code Reviewer.

**When you open a PR, Tenki Code Reviewer posts two live comments simultaneously:**

1. Summary
2. Review Comment

**Both comments:**

* Appear as soon as analysis starts
* Update dynamically while the review is running
* Reach their final state when the 👍 icon appears

**Live Status**

| Status    | Emoji | Meaning                                                      |
| --------- | ----- | ------------------------------------------------------------ |
| Analyzing | 👀    | Tenki is building context and reviewing the PR (\~3 minutes) |
| Complete  | 👍    | Analysis finished                                            |
| Failed    | 😕    | Tag `@tenki-reviewer` to retry                               |

## Manual PR Review

You can trigger a code review manually by tagging `@tenki-reviewer` in a comment. This is especially useful for reviewing older PRs created before Tenki Code Reviewer was integrated.

![Pull request comment triggering a review with @tenki-reviewer](https://tenki.cloud/images/get-started/tcr-step5.png)

# Tenki for Startups: Program Terms and Conditions (https://tenki.cloud/docs/startups-program-terms)

Last Updated: July 20, 2026


## 1. Introduction and Acceptance

These Program Terms and Conditions (the "**Program Terms**") govern participation in the Tenki for Startups program (the "**Program**") offered by Tenki Cloud, LLC, a wholly owned subsidiary of Luxor Technology Corporation ("**Tenki**," "we," "us," or "our"). The Program is operated by Tenki.

By applying to, enrolling in, or participating in the Program, the applicant and, if accepted, the participating company ("**Participant**," "you," or "your") agrees to these Program Terms. These Program Terms are in addition to, and incorporate by reference, Tenki's [Terms of Service](https://tenki.cloud/docs/terms-of-service.md), [Acceptable Use Policy](https://tenki.cloud/docs/acceptable-use-policy.md), and [Privacy Policy](https://tenki.cloud/docs/privacy-policy.md) (collectively, the "**General Terms**"), each as updated from time to time. In the event of a conflict between these Program Terms and the General Terms with respect to the Program, these Program Terms control.

### 1.1 Defined Terms; Relationship to General Terms

Capitalized terms used but not defined in these Program Terms have the meanings given in the General Terms. For purposes of the General Terms, each Participant is a "Customer" and each of its authorized users is a "User." "Workspace" means the Participant's Tenki account or organization, and "Program usage" means any use of the Services funded by Credits. No Order Form is required to participate; acceptance under Section 3 is the operative enrollment.

If you do not agree to these Program Terms, you may not participate in the Program.

## 2. Eligibility

### 2.1

To be eligible to apply, an applicant must, at the time of application, meet all of the following criteria:

* (a) have raised no more than US$10,000,000 in aggregate external funding;
* (b) be at or before its Series B financing stage;
* (c) have fewer than 100 employees; and
* (d) have been in operation for fewer than five (5) years.

### 2.2

Eligibility criteria are minimum thresholds only. Meeting the criteria does not entitle any applicant to acceptance into the Program.

### 2.3

Tenki may modify the eligibility criteria at any time. Tenki may request documentation to verify eligibility and may reject or remove any Participant that does not meet, or ceases to meet, the criteria or that provides inaccurate information.

## 3. Application and Acceptance

### 3.1

Applications are reviewed on a rolling basis. Tenki accepts applicants into the Program in its sole and absolute discretion, and may decline any application for any reason or no reason.

### 3.2

Tenki is under no obligation to accept any minimum or maximum number of applicants, and may open, pause, close, or limit applications at any time.

### 3.3

Acceptance is effective only upon Tenki's written or electronic confirmation of acceptance to the Participant.

## 4. Program Benefits

### 4.1 Program Credits

Upon acceptance, Tenki will apply US$10,000 in promotional credits ("**Program Credits**") to the Participant's Tenki workspace. Program Credits may be applied toward eligible Tenki products and services as described in Section 5.

### 4.2 Matching Credits

For each additional dollar of Tenki credit the Participant purchases during the Program period, Tenki will match that purchase with an additional credit on a 1:1 basis, up to a maximum of US$40,000 in matching credits ("**Matching Credits**"). Matching Credits are promotional credits subject to the same restrictions as Program Credits.

### 4.3 Perks

Subject to availability and to Tenki's policies, accepted Participants may also receive: access to a Program Slack community and engineering office hours; invitations to Tenki events; a merchandise package; inclusion in Tenki's ecosystem and customer listings (see Section 7); and access to Tenki's San Francisco office subject to Tenki's visitor policy and a separate visitor and confidentiality acknowledgment.

### 4.4

Perks are provided as a courtesy, are subject to change or withdrawal at any time, and are not a contractual entitlement.

## 5. Credit Mechanics, Restrictions, and Product Eligibility

### 5.1 Promotional Nature

Program Credits and Matching Credits (collectively, "**Credits**") are promotional only. Credits: (a) have no cash value; (b) are non-transferable and non-assignable; (c) are non-refundable and non-redeemable for cash; (d) may not be sold, brokered, or combined with other offers except as expressly permitted; and (e) do not constitute a deposit, prepayment, security, or property interest.

### 5.2 Expiration

Credits expire on the earlier of (a) the date that is twelve (12) months after the date they are applied to the Participant's workspace, or (b) termination of the Participant's participation in the Program or Tenki account. Expired or forfeited Credits are not recoverable and have no value.

### 5.3 Product Eligibility and Per-Product Limits

Tenki may designate which products and services are eligible for Credits, and may establish, change, or remove per-product caps, usage thresholds, and rate limits on Credit usage at any time, including for specific products such as AI Code Reviewer. Tenki may exclude or limit the use of Credits for any product in its discretion. Tenki will disclose the existence of per-product caps in the Program's published materials, and any public statement that Credits may be used across the Tenki suite is qualified by this Section.

### 5.4 Service Tier and Model Routing

Tenki may provision Program usage using designated service tiers, infrastructure, and underlying models, and may route or reassign Program usage to alternative or lower-cost models, tiers, or infrastructure at any time. Tenki does not guarantee access to any particular model, tier, feature, or performance level for Program usage.

### 5.5 Order of Application

Tenki determines the order in which Credits are applied against usage and may apply Credits, paid balances, and discounts in the order it determines.

## 6. Service Availability; No Service Levels for Program Usage

### 6.1

Program usage, including all usage funded by Credits, is provided on an "as available" basis.

### 6.2

No service level commitment applies to Program usage. Any uptime, availability, or service level commitments in the General Terms or in any paid plan do not apply to Program usage, consistent with Section 2.2 of the Terms of Service (Free Trials). Tenki does not warrant uninterrupted or error-free Program usage.

### 6.3 Priority and Capacity

Tenki may prioritize paying customers over Program usage and may throttle, rate-limit, suspend, or reallocate Program usage during periods of constrained capacity or for operational, security, or economic reasons, without liability.

## 7. Trademarks, Logos, and Publicity

### 7.1 License to Tenki

Participant grants Tenki a non-exclusive, worldwide, royalty-free, revocable license to use Participant's name, logo, and trademarks (a) to identify Participant as a Program participant and Tenki customer, and (b) in Tenki's marketing materials, website, "ecosystem" / "built with Tenki" listings, and customer references. Participant may revoke this license prospectively on written notice, after which Tenki will cease new uses within a commercially reasonable period; provided that the license is irrevocable for the duration of the Participant's participation in the Program with respect to identifying Participant as a Program participant.

### 7.2 License to Participant

Subject to Tenki's brand guidelines, Tenki grants Participant a non-exclusive, non-transferable, revocable license to use Tenki's name and logo solely to indicate that Participant builds on or uses Tenki (for example, "Built on Tenki"). Participant may not use Tenki's marks in any manner that implies endorsement, sponsorship, partnership, or certification beyond participation in the Program, or in any false or misleading manner.

### 7.3 Press and Named References

Neither party will issue a press release or use the other's name in a marquee or headline manner without the other party's prior written consent (which may be given by email).

### 7.4

Each party retains all right, title, and interest in its own marks. All goodwill from use of a party's marks inures to that party.

## 8. Data, Privacy, and Communications

### 8.1

Tenki's collection and use of application and account data is governed by Tenki's [Privacy Policy](https://tenki.cloud/docs/privacy-policy.md). By applying, Participant consents to Tenki's processing of the information submitted for purposes of administering the Program.

### 8.2 Marketing Communications

By applying, Participant agrees that Tenki may contact Participant regarding the Program and related Tenki offerings. Marketing communications are subject to applicable law, including the CAN-SPAM Act and, where applicable, Canada's Anti-Spam Legislation (CASL) and other regional requirements. Participant may opt out of non-transactional communications at any time. Tenki will capture marketing consent through an explicit, separately-checked opt-in in the application form.

### 8.3 International Participants

Where applicable, Tenki processes personal data in accordance with the GDPR, CCPA/CPRA, and other applicable data protection laws, as described in the Privacy Policy.

## 9. Acceptable Use and Compliance

### 9.1

Participant's use of Tenki remains subject at all times to the [Acceptable Use Policy](https://tenki.cloud/docs/acceptable-use-policy.md) and the General Terms.

### 9.2

Participant may not: create multiple or duplicate accounts to obtain additional benefits; resell, transfer, or monetize Credits or benefits; misrepresent eligibility; or use the Program to circumvent pricing, caps, or limits.

### 9.3

Participant is responsible for compliance with all applicable laws, including export controls, sanctions, and anti-money-laundering requirements, in connection with its use of Tenki.

## 10. Modification, Suspension, and Termination

### 10.1

Tenki may modify, suspend, or discontinue the Program, or any benefit, in whole or in part, at any time, with or without notice.

### 10.2

Tenki may modify these Program Terms at any time. Tenki will make reasonable efforts to notify Participants of material changes, consistent with Section 6 of the Terms of Service. Continued participation after changes take effect constitutes acceptance of the revised Program Terms.

### 10.3

Tenki may suspend or terminate a Participant's participation, and revoke unused Credits, immediately if the Participant breaches these Program Terms or the General Terms, becomes ineligible, engages in fraud or abuse, or for any other reason in Tenki's discretion. Tenki will notify the Participant as early as commercially reasonable.

### 10.4

On termination of participation for any reason, all unused Credits and unredeemed benefits are immediately forfeited. For clarity, amounts actually paid by the Participant (as opposed to promotional Credits, which have no cash value) are governed by Section 5.2 of the Terms of Service, including any refund of prepaid, unused fees on termination for cause by the Participant.

## 11. Disclaimers and Limitation of Liability

### 11.1

The Program and all Program usage are provided "as is" and "as available," without warranties of any kind, to the maximum extent permitted by law. Tenki disclaims all implied warranties, including merchantability, fitness for a particular purpose, and non-infringement, with respect to the Program.

### 11.2

To the maximum extent permitted by law, Tenki will not be liable for any indirect, incidental, special, consequential, or exemplary damages, or for any lost profits or data, arising out of or relating to the Program. Tenki's total aggregate liability arising out of or relating to the Program will not exceed US$100.

### 11.3

The limitations in this Section apply notwithstanding any failure of essential purpose. With respect to any matter arising out of or relating to the Program, the limitations in this Section are the sole and controlling limitations of Tenki's liability and apply in place of, and not in addition to, any limitation of liability in the General Terms.

## 12. General

### 12.1 Relationship

The Program does not create any partnership, joint venture, agency, fiduciary, or employment relationship, or any equity, investment, or ownership interest, between the parties. The benefits are not grants of equity or securities.

### 12.2 No Inducement of Breach

Nothing in the Program is intended to induce any Participant to breach any agreement with a third party, including any existing vendor or platform agreement.

### 12.3 Governing Law

These Program Terms are governed by the laws of the State of Montana, without regard to conflict-of-laws principles. The parties submit to the exclusive jurisdiction of the state and federal courts located in Billings (Yellowstone County), Montana.

### 12.4 Entire Agreement

These Program Terms, together with the General Terms, constitute the entire agreement regarding the Program and supersede prior understandings regarding its subject matter.

### 12.5 Severability; Waiver

If any provision is held unenforceable, the remaining provisions remain in effect. No waiver is effective unless in writing.

### 12.6 Assignment

Participant may not assign these Program Terms or any benefit without Tenki's prior written consent. Tenki may assign freely.

### 12.7 Survival

Sections 5.1, 6, 7, 8, 11, and 12 survive any expiration or termination of a Participant's participation in the Program.

# Socials (https://tenki.cloud/docs/tenki-socials)

Want updates, releases, and quick help? Here’s where to find us.

Want product updates, new releases, and quick help? Here's where to find Tenki and the best channel for what you need.

## Where to follow us

* **Discord:** the fastest way to reach the team and the wider community. Ask setup questions, share feedback, report issues, and see what other engineering teams are building on Tenki.
* **X (Twitter):** product announcements, release highlights, benchmarks, and the occasional behind-the-scenes look at how we build.
* **GitHub:** follow along, see what we're shipping, and explore projects built with Tenki.

## Where should I ask for help?

* **Quick question or setup help?** Hop into **Discord**, the fastest path to an answer.
* **Account, billing, or something sensitive?** Email [hello@tenki.cloud](mailto:hello@tenki.cloud) so we can look into it privately.
* **Just want to keep up with releases?** Follow us on **X**.

You can also browse the [documentation](https://tenki.cloud/docs.md) anytime for guides on runners, code review, and sandboxes.

# Terms of Service (https://tenki.cloud/docs/terms-of-service)

Last Updated: July 20, 2026


This Agreement is a contract entered into by and between you ("**Customer**," "you," or "your") and Tenki Cloud, LLC, a wholly owned subsidiary of Luxor Technology Corporation ("**Tenki**," "we," "us," or "our") and our affiliates, to the extent expressly stated. These Terms of Service (together with our Privacy Policy and [Acceptable Use Policy](https://tenki.cloud/docs/acceptable-use-policy.md), this "**Agreement**") govern your access to and use of our cloud services, AI-powered code review capability, software, and related offerings (including Tenki Sandboxes, the AI Code Reviewer, and GitHub Actions Runners) (collectively, the "**Services**").

Please read this Agreement carefully before using our Services. By accessing or using the Services, you accept and agree to be bound by these Terms. If you do not agree, you do not have permission to use the Services.

***

## 1. Eligibility

The Services are intended solely for individuals who are at least 18 years of age and have the legal capacity to enter into binding contracts under applicable law. By using the Services, you represent and warrant that you meet these requirements and that you are not a resident of, or accessing the Services from, a jurisdiction subject to embargoes, sanctions, or other restrictions under applicable U.S. laws and regulations.

## 2. Provision of Services

### 2.1 Grant

Subject to the terms of this Agreement, Tenki grants Customer a worldwide, non-exclusive, non-sublicensable, and non-transferable right, and with respect to Self-Hosted Services, a license, to access and use the Services during the Term solely for Customer's internal business purposes. For Services purchased through self-service sign-up rather than a negotiated order, the plan the Customer selects at sign-up, together with Tenki's published pricing page, constitutes the applicable "Order Form." Tenki may modify the Services from time to time at its sole discretion, provided modifications do not materially diminish functionality.

### 2.2 Free Trials

Any services provided at no charge ("Free Trial") are subject to this Agreement. Tenki reserves the right to modify or cancel any Free Trial at any time without notice. Free Trials are provided without representations, warranties, support, or SLAs, and Tenki's liability with respect to Free Trials is limited to an aggregate of $1,000.

### 2.3 No Other Rights

The license granted to Customer is expressly set forth above. No other rights or licenses are granted, whether by implication, estoppel, or otherwise. All rights not expressly granted are reserved by Tenki.

### 2.4 No Support

Tenki is under no obligation to provide support for the Services. Where support is offered, it will be subject to published policies and fees as agreed in an Order Form.

### 2.5 Product-Specific Terms

**Sandboxes.** Tenki Sandboxes are hosted compute environments. Customer is solely responsible for the code, data, and workloads it runs in a Sandbox and for compliance with the Acceptable Use Policy. Sandbox resources are metered and subject to the limits of the applicable plan, and Tenki may suspend or reclaim Sandbox resources for capacity, security, or non-payment. Sandbox contents may be permanently deleted upon expiration or termination of the applicable plan.

**AI Code Reviewer.** Code Reviewer output is generated by artificial intelligence, is advisory only, and may be inaccurate or incomplete. Customer is responsible for independently reviewing and validating any output before relying on it, and Section 3.3 governs the use of third-party AI providers.

**GitHub Actions Runners.** Runners execute workflows through GitHub Actions. Customer is responsible for its use of GitHub and compliance with GitHub's terms, for the security and configuration of any self-hosted or connected runner, and for the content of the workflows it executes.

## 3. Customer Accounts; Third-Party Accounts

### 3.1 Customer Accounts

To use the Services, Customer must register for a Tenki account. Customer is responsible for maintaining the security and confidentiality of its account credentials and is solely responsible for all losses incurred due to unauthorized use resulting from Customer's failure to keep account information secure. Customer may opt out of data storage; however, opting in helps Tenki enhance the quality of reviews based on Customer's usage.

### 3.2 Third-Party Accounts

Registering an account requires connecting to a pre-existing account with a supported code repository platform (e.g., GitHub, etc.. ) (each, a "Third-Party Account"). By connecting a Third-Party Account, Customer authorizes Tenki to access that account solely to provide the Services. Tenki does not license or endorse, and has no liability related to, any Third-Party Accounts.

Customer represents and warrants that it has all necessary rights, consents, and permissions to grant Tenki access to its Third-Party Account without breaching any terms with the applicable provider or subjecting Tenki to any payment obligations or liabilities.

### 3.3 AI

The Services use artificial intelligence powered by Anthropic and OpenAI via API integration. Customer's proprietary code remains confidential with Tenki. While code is shared with Anthropic and/or OpenAI to perform reviews, Tenki maintains a **zero data retention policy** with both providers.

Tenki is not responsible for the accuracy, completeness, timeliness, or quality of any output or content provided by third-party AI providers, provided that Tenki will use commercially reasonable efforts to monitor third-party outputs delivered to Customers as part of the Services.

## 4. Customer Obligations

### 4.1 Responsibilities

Customer agrees to use the Services only in accordance with this Agreement and in compliance with all applicable laws, rules, and regulations, including export control, sanctions, and anti-boycott laws. Customer is responsible for Users' use of the Services, and any breach by a User constitutes a breach by Customer. Customer will promptly notify Tenki if it becomes aware of any illegal use of the Services.

Customer also agrees to:

* Provide and maintain accurate, complete, and current account information.
* Complete any Know Your Customer ("KYC") and Anti-Money Laundering ("AML") verification processes upon request.
* Maintain the confidentiality of account credentials and not permit unauthorized access.

### 4.2 Prohibited Conduct

Customer and its Users shall not, and shall not permit or assist any party to:

* (i) Use the Services in violation of any applicable law, regulation, or export control requirement, or to infringe the Intellectual Property Rights of any third party.
* (ii) Decompile, disassemble, reverse engineer, or attempt to derive the source code, structure, or algorithms of the Services.
* (iii) Copy, modify, distribute, rent, sell, sublicense, or otherwise transfer the Services or any portion thereof.
* (iv) Disclose the results of any benchmarking of the Services, or use the Services to develop competing products or services without Tenki's prior written consent.
* (v) Circumvent or disable any security or access controls, or use the Services in any manner that disrupts or impairs Tenki's systems or other users' access.
* (vi) Use automated tools (including robots, spiders, or scripts) to extract data from the Services, or introduce any viruses, malware, or other harmful code.
* (vii) Deploy malicious code or engage in any activity constituting a distributed denial-of-service (DDoS) attack or similar disruption.

### 4.3 Acceptable Use Policy

Customer's use of the Services is also subject to Tenki's [Acceptable Use Policy](https://tenki.cloud/docs/acceptable-use-policy.md), which is incorporated by reference. Without limiting the above, Customer shall not use Sandboxes, Runners, or other compute resources for cryptocurrency mining, denial-of-service, unlawful, infringing, or abusive workloads, and Tenki may suspend usage that threatens the security, integrity, or availability of the Services.

## 5. Term and Termination

### 5.1 Term

The initial Term shall be as specified in the Order Form. This Agreement and each Order Form shall automatically renew for a period equal to the expiring Term unless either party provides at least **45 days'** prior written notice of non-renewal.

### 5.2 Termination for Cause

Either party may terminate this Agreement or an Order Form for cause:

* (i) if the other party is in material breach and fails to cure within **30 days** of written notice; or
* (ii) immediately if the other party becomes subject to bankruptcy, insolvency, receivership, or assignment for the benefit of creditors. Upon termination for cause by Customer, Tenki shall refund any prepaid, unused fees for the remaining Term.

### 5.3 Suspension or Termination by Tenki

Tenki may suspend or terminate access to the Services:

* (i) to prevent harm to Tenki or any third party, including in response to fraudulent or illegal activity;
* (ii) upon 30 days' notice for failure to pay fees when due; or
* (iii) upon request of law enforcement or government agencies. Tenki will notify Customer as early as commercially reasonable.

### 5.4 Self-Service Subscriptions

Notwithstanding Section 5.1, for self-service subscriptions, the applicable plan renews automatically for successive periods (e.g., monthly or annual) at the then-current published price until cancelled. Customer may cancel at any time through its account, effective at the end of the current billing period; fees already paid are non-refundable except as required by law or expressly stated in this Agreement. Upon termination or expiration, Customer's access ends and Tenki may delete Customer content and Sandbox data after a commercially reasonable period.

## 6. Modifications to Terms

Tenki reserves the right to revise, modify, or update these Terms at any time, in its sole discretion. We will make reasonable efforts to notify you of material changes, which may include updating the "Last Updated" date above and, at our discretion, notifying you by email, consistent with our Privacy Policy. Your continued use of the Service after any such changes become effective constitutes your acceptance of the revised Terms.

## 7. Privacy Policy

Your use of the Service is subject to Tenki’s Privacy Policy, which is incorporated by reference into these Terms. The Privacy Policy outlines the types of information we collect, how we use that information, and the rights and choices available to users with respect to their personal data. By accessing or using the Service, you acknowledge that you have reviewed and consent to the practices described in the Privacy Policy. Tenki processes personal data as described in the Privacy Policy, including its international-transfer safeguards, and will make a Data Processing Addendum available to business customers on request.

## 8. Intellectual Property Rights

All content, features, and functionality of the Service, including but not limited to the Tenki name, logo, software, interfaces, and other intellectual property, are owned by or licensed to Tenki and are protected under applicable intellectual property laws.

You retain all rights and ownership of the content that you submit, upload, or transmit through the Service. By using the Service, you grant Tenki a worldwide, royalty-free, sublicensable, and transferable license to use, host, store, reproduce, modify, and display such content as reasonably necessary to provide and improve the Service.

### 8.1 Feedback

If Customer provides suggestions, ideas, or other feedback regarding the Services, Tenki may use that feedback without restriction or obligation, and Customer grants Tenki a perpetual, irrevocable, royalty-free license to do so.

## 9. Compliance with Laws

You agree to comply with all applicable laws, rules, and regulations in connection with your use of the Service. Tenki reserves the right to immediately suspend or terminate access to the Service without refund or recourse if we become aware of any unlawful conduct or violation of applicable law by you.

## 10. Fees, Payment, and Taxes

### 10.1 Fees

Customer will pay the fees for the Services at the prices set out on Tenki's published pricing page or the applicable plan selected at sign-up. Fees may be based on subscription and/or metered usage (including Sandbox compute, Code Reviewer usage, and Runner minutes).

### 10.2 Payment

Payments are processed by our third-party payment processor (Stripe). Customer authorizes Tenki and its processor to charge the payment method on file for all fees when due. Except as required by law or expressly stated in this Agreement, all fees are non-refundable.

### 10.3 Taxes

Fees are exclusive of taxes. Customer is responsible for all sales, use, VAT, GST, and similar taxes, excluding taxes based on Tenki's net income.

### 10.4 Late or Failed Payment

If a payment fails or is overdue, Tenki may suspend or terminate the Services in accordance with Section 5.3 and may charge interest on overdue amounts to the extent permitted by law.

### 10.5 Price Changes

Tenki may change its prices; changes apply to the next renewal term and, where required, on prior notice.

### 10.6 Promotional Credits

Promotional or program credits (including under the Tenki for Startups program) are governed by the applicable Program Terms and have no cash value.

## 11. Service Availability

The Services are provided on an "as available" basis. Unless a separate written service level agreement applies, Tenki does not commit to any specific uptime or availability and may perform maintenance, and may throttle or suspend usage for capacity, security, or operational reasons. Service levels do not apply to Free Trials or to promotional/program usage.

## 12. Disclaimer of Warranties

EXCEPT AS EXPRESSLY STATED IN THIS AGREEMENT, THE SERVICES ARE PROVIDED "AS IS" AND "AS AVAILABLE," AND TENKI DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, IMPLIED, OR STATUTORY, INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT. TENKI DOES NOT WARRANT THAT THE SERVICES WILL BE UNINTERRUPTED, ERROR-FREE, OR SECURE, OR THAT AI-GENERATED OUTPUT WILL BE ACCURATE OR COMPLETE.

## 13. Limitation of Liability

### 13.1

TO THE MAXIMUM EXTENT PERMITTED BY LAW, NEITHER PARTY WILL BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR EXEMPLARY DAMAGES, OR FOR LOST PROFITS, REVENUE, DATA, OR GOODWILL, ARISING OUT OF OR RELATING TO THIS AGREEMENT.

### 13.2

EXCEPT FOR CUSTOMER'S PAYMENT OBLIGATIONS AND EACH PARTY'S INDEMNIFICATION OBLIGATIONS, EACH PARTY'S TOTAL AGGREGATE LIABILITY ARISING OUT OF OR RELATING TO THIS AGREEMENT WILL NOT EXCEED THE GREATER OF (A) THE FEES PAID BY CUSTOMER TO TENKI IN THE TWELVE (12) MONTHS PRECEDING THE CLAIM OR (B) US$100. LIABILITY FOR FREE TRIALS AND PROMOTIONAL USAGE IS FURTHER LIMITED AS STATED IN SECTION 2.2 AND THE APPLICABLE PROGRAM TERMS.

## 14. Indemnification

Customer will defend, indemnify, and hold harmless Tenki and its affiliates from and against any third-party claims, damages, and costs (including reasonable attorneys' fees) arising out of or relating to Customer's content, its workloads or code run on the Services (including Sandboxes and Runners), its use of the Services, or its breach of this Agreement or applicable law.

## 15. Confidentiality

Each party may receive confidential information of the other. The receiving party will use it only to perform under this Agreement, protect it with reasonable care, and not disclose it except to those who need to know and are bound by similar obligations. This does not apply to information that is public, independently developed, or rightfully obtained without a duty of confidentiality, or where disclosure is legally required.

## 16. Promotional Programs

Participation in Tenki promotional programs, including the Tenki for Startups program, is subject to the applicable Program Terms, which are in addition to and control over this Agreement with respect to that program.

## 17. Governing Law; Venue; Dispute Resolution

This Agreement is governed by the laws of the State of Montana, without regard to conflict-of-laws principles. The parties submit to the exclusive jurisdiction of the state and federal courts located in Billings (Yellowstone County), Montana.

## 18. General

### 18.1 Assignment

Customer may not assign this Agreement without Tenki's prior written consent; Tenki may assign it, including to an affiliate or in connection with a merger, acquisition, or sale of assets.

### 18.2 Notices

Tenki may provide notices by email or through the Services; Customer notices must be sent to the address in Section 19.

### 18.3 Force Majeure

Neither party is liable for delays or failures caused by events beyond its reasonable control.

### 18.4 Entire Agreement; Order of Precedence

This Agreement, the Privacy Policy, the Acceptable Use Policy, and any applicable Order Form or Program Terms are the entire agreement and supersede prior understandings. In the event of conflict, an applicable Program Terms controls for its program, then the Order Form, then these Terms.

### 18.5 Severability; Waiver

If any provision is unenforceable, the remainder stays in effect; no waiver is effective unless in writing.

### 18.6 No Third-Party Beneficiaries; Relationship

There are no third-party beneficiaries, and the parties are independent contractors.

### 18.7 Survival

Sections 2.3, 4, 8, 10–15, 17, and 18 survive termination or expiration.

## 19. Contact Information

If you have any questions about these Terms, please contact us at [hello@tenki.cloud](mailto:hello@tenki.cloud), or by mail at Tenki Cloud, LLC, 235 Moore Lane, Suite 120, Billings, MT 59101, USA.

# Manage API Keys (https://tenki.cloud/docs/account/api-keys)

Create, store, rotate, and revoke Tenki API keys for Sandbox SDKs, CLI automation, and CI.

Tenki API keys authenticate the Sandbox SDKs and non-interactive CLI sessions. A key begins with `tk_`, and the
SDKs read it from the `TENKI_API_KEY` environment variable by default. Tenki Runners and Code Reviewer use their
GitHub App connections instead of API keys.

## Create an API key

1. [Sign in to the Tenki dashboard](https://app.tenki.cloud) and select **Tenki Sandbox**.
2. Complete Sandbox onboarding. Tenki creates the initial API key for you; copy it when it is shown and save it
   in your shell or secret manager.
3. To create another key or control expiration, open **API Keys** and select **Create API Key**.
4. Enter a **Key Name**, optionally select an expiration date, and select **Create Key**.
5. Copy the new key when it is shown and store it securely.

![Create API key dialog in the Tenki dashboard](https://tenki.cloud/images/docs/sandbox/create-api-key.png)

## Use the key

Export the key before running an SDK program:

```bash
export TENKI_API_KEY=tk_your_api_key
```

For a non-interactive CLI login, pass the same value directly:

```bash
tenki login --api-key tk_your_api_key
tenki status
```

Each API key belongs to exactly one workspace. Sandbox requests infer that workspace from the key, so normal CLI
and SDK calls do not need a workspace ID.

## Rotate or revoke a key

To rotate a key without interrupting automation:

1. Create a replacement key.
2. Update every application, CI secret, or secret manager that uses the old key.
3. Verify the replacement key with `tenki status` or an SDK request.
4. Return to **API Keys**, select the delete button beside the old key, and confirm **Revoke API Key**.

Revocation takes effect immediately and cannot be undone.

## Keep keys secure

* Store keys in a secret manager or your CI provider's encrypted secrets.
* Never commit a key to source control or paste one into an issue, pull request, or support message.
* Use descriptive names so you can identify each key's owner and purpose.
* Set an expiration date appropriate for the workload and revoke keys that are no longer used.
* If a key is exposed, replace it and revoke the exposed key immediately.

# How Billing works in Tenki (https://tenki.cloud/docs/account/billing)

Understand how billing works in Tenki for GitHub Actions runners. Learn about usage-based pricing, free credits, and how Tenki delivers cost improvements over runners alternatives.

We only start charging when a job actually begins running; time spent in the queue is not billed. Usage is charged per minute, with each started second rounded up to the next second. For example, if a job runs for 2 minutes, 56 seconds, and a fraction of a second, it will be billed as 2 minutes and 57 seconds.

## Scale to zero

Tenki bills for **consumed minutes only**. You don't pay for:

* Weekends or overnight when nothing runs
* A standby or warm pool (there isn't one, every job boots a fresh VM)
* Time after a job completes (VMs are destroyed immediately)

The only recurring charge outside per-minute usage is your plan fee and any active add-ons. See [Limits, Concurrency & Cold Start](https://tenki.cloud/docs/runners/limits-and-concurrency.md) for the full operational picture.

## How billing cycle works

**Step 1:**
### Billed events review

For each of your workspaces, we track the number of billable events generated during the month (refer to the section above for details on how an event is considered billable).

**Step 2:**
### Free Credits review We check your remaining free credits and deduct them from your total usage.

**Step 3:**
### An invoice is generated and the payment is processed.

For every workspace, we monitor the total number of billable events created during the month (see the section above for an explanation of what qualifies as a billable event).

> **Important:** If an invoice is not paid on time, service will be interrupted and any running jobs will be automatically canceled. To avoid this, make sure a payment method is added to your workspace.

# How Free Credits Works (https://tenki.cloud/docs/account/free-credits)

Learn how free credits work in Tenki and how to use them to run GitHub Actions runners with better performance and cost improvements.

Every Tenki Starter workspace includes **$10 in free monthly credits**, automatically renewed on the 1st of each month and applied to your oldest (default) workspace.

### How you get your Free Credits

Create your Tenki account and your workspace starts with $10 in credits immediately. You can begin running CI workflows, triggering code reviews, or spinning up sandboxes.

On the 1st of every month, your Starter workspace is topped back up to $10 in free credits.

### How Free Credit Usage Is Calculated

Credits are spent at the same per-unit rates as paid usage. For a 2 vCPU x64 runner billed at **$0.002 per core / minute**, $10 in credits buys roughly **2,500 minutes** per month. Larger runners burn credits proportionally faster — a 4 vCPU runner burns at $0.008/min, an 8 vCPU runner at $0.016/min.

See [the pricing page](https://tenki.cloud/docs/pricing.md) for the full per-unit rate card across all products.

### When you exceed your free credits

Usage beyond the $10 monthly allowance is billed at the standard per-unit rates listed on [the pricing page](https://tenki.cloud/docs/pricing.md). The Team plan ($200/month yearly, $250/month monthly) raises the included credit allowance to $100 / month and adds higher concurrency, larger runner sizes, and premium infrastructure.

> **Need more than the Team plan?:** Enterprise plans include custom credit allowances, self-hosting, SLAs, and dedicated support. Email hello@tenki.cloud to scope a plan.

# Manage Members and Settings (https://tenki.cloud/docs/account/members-and-settings)

Manage Tenki Cloud members, projects, and workspace settings. Invite team members, assign roles, & configure your cloud environment for peak collaboration.

## Members Management

This section allows you to manage user access across your Workspace and Projects from inviting new members to adjusting roles or removing users as needed. It provides centralized control over who can access and collaborate within your environment.

### How to Invite new Members

**Step 1:**
Go into the **Members** page

> **Important:** Only Owner and Admin roles can manage members in the Workspace.

![MembersPage](https://tenki.cloud/images/settings/members-page.png)

**Step 2:**
Enter the user information and select the role

![InvitationProcess](https://tenki.cloud/images/settings/invitation-process.png)

**Step 3:**
The user will complete onboarding and automatically receive the access level you’ve assigned.

### How to manage existing Members

To manage or update an existing user's role, go to the **Current Members** table, click the **Actions** icon next to their name, and select **Edit**.

[Video](https://storage.googleapis.com/tenki-cloud-assets/docs/update-user-role.mp4)

## Settings

### How to manage your account settings

In the **Account** section, you can set your full name for billing purposes, manage your password, and enable two-factor authentication (2FA). Please note that this email will be used for all communications from Tenki.

![ProfileSettings](https://tenki.cloud/images/settings/profile-settings.png)

### Find your Workspace ID

Open [Tenki Cloud](https://app.tenki.cloud), select **Settings** in the sidebar, and copy the value in the
**Workspace ID** field. This stable identifier may be requested by support. Normal Sandbox CLI and SDK requests
infer the workspace from the API key and do not need this ID.

![WorkspaceSettings](https://tenki.cloud/images/settings/workspace-settings.png)

Workspace Settings also lets you rename the workspace and its slug, manage connected applications and
repositories, and, depending on your role, delete or leave the workspace. API keys are managed separately; see
[Manage API Keys](https://tenki.cloud/docs/account/api-keys.md).

### How to manage your projects

The **Project Settings** allow you to update the Project name and, depending on your role, either delete the project or leave it.

![ProjectSettings](https://tenki.cloud/images/settings/project-settings.png)

# Manage Payments and Plans (https://tenki.cloud/docs/account/payment)

Update your payment details, switch plans, review past invoices, and manage your subscription settings quickly and securely.

## Plans Management

Tenki offers two plans to fit different needs:

1. Pay-as-you-go
   Set a daily or monthly spending limit that you can adjust at any time, with competitive rates. This plan also includes $10 in free credits every month, renewed automatically.
2. Team Plan
   Designed for larger teams, this plan provides a fixed credit allowance to support higher usage needs.
   Regardless of which plan you choose, once your balance is funded you'll have full access to all three Tenki applications and every feature on the platform.

   ![Tenki Billing page overview](https://tenki.cloud/images/billing-docs/billing-step1.png)

### PAYG Plan

**Step 1:**
Access **Billing** page and select `Add Funds`

![Add Funds button on the Billing page](https://tenki.cloud/images/billing-docs/billing-upgrade-payg.png)

**Step 2:**
Enter the amount you'd like to allocate to your balance

> **Important:** Enable auto-funding on your balance to avoid manual top-ups and prevent service interruptions.

![Funding amount entry dialog](https://tenki.cloud/images/billing-docs/billing-payg-step2.png)

**Step 3:**
Complete the transaction on Stripe

![Stripe checkout for PAYG funding](https://tenki.cloud/images/billing-docs/billing-payg-step3.png)

### Teams Plan

**Step 1:**
Access **Billing** page and select `Upgrade to Team`

![Upgrade to Team button on the Billing page](https://tenki.cloud/images/billing-docs/billing-upgrade-team.png)

**Step 2:**
Select if you prefer `Monthly` or `Annual` payment

![Monthly vs Annual billing selection](https://tenki.cloud/images/billing-docs/billing-team-step1.png)

**Step 3:**
Complete the transaction on Stripe

![Stripe checkout for Team plan upgrade](https://tenki.cloud/images/billing-docs/billing-team-step2.png)

# Workspace Roles and Permissions (https://tenki.cloud/docs/account/roles-perms)

Tenki Cloud's role-based access system. Learn about Owner, Admin, and Standard roles, workspace vs. project scopes, and detailed permission breakdowns.

Roles are designed to help admins create tailored environments that align with their specific use cases.

Currently, a user can be assigned **only one role per workspace**. For example, a user might have an `admin` role in one workspace, while holding a `standard` role in another.

## Roles

We currently support the following roles:

| Role         | Description                                                                               |
| ------------ | ----------------------------------------------------------------------------------------- |
| **Owner**    | Automatically assigned upon Workspace creation. Provides full control over the Workspace. |
| **Admin**    | Full access to manage resources, configurations, and settings.                            |
| **Standard** | Focused on day-to-day operations within assigned workspace and projects.                  |

> **Important:** Workspace ownership transfer is not currently supported.

## Scopes

Tenki supports two access levels: `Workspace` and `Projects`, allowing permissions to be granted at either level. The scope is defined when inviting a user but can also be adjusted later from the `Members` page.

| Scope                | Description                                                                                              |
| -------------------- | -------------------------------------------------------------------------------------------------------- |
| **Full Workspace**   | Includes access to all projects currently in the workspace, as well as any that are added in the future. |
| **Project Specific** | Access restricted to **selected projects** only.                                                         |

> **Important:** Scope determines access areas, not permissions. Admins and Standard users have the same actions, whether at the workspace or project level.

## Action-Based Permissions

The table below outlines the actions available for each role:

| Actions                   | Owner | Administrator | Standard |
| ------------------------- | ----- | ------------- | -------- |
| View Workspace Dashboard  | ✅     | ✅             | ✅        |
| Create Workspace          | ✅     | ✅             | ✅        |
| Edit Workspace Settings   | ✅     | ✅             | ❌        |
| Delete Workspace          | ✅     | ✅             | ❌        |
| View Project Dashboard    | ✅     | ✅             | ✅        |
| Access Runners Activity   | ✅     | ✅             | ✅        |
| Create Project            | ✅     | ✅             | ❌        |
| Connect GitHub Org / Repo | ✅     | ✅             | ❌        |
| Edit Project Settings     | ✅     | ✅             | ❌        |
| Delete Project            | ✅     | ✅             | ❌        |
| View Members              | ✅     | ✅             | ❌        |
| Edit Members Access       | ✅     | ✅             | ❌        |
| Invite New Members        | ✅     | ✅             | ❌        |
| Trigger Workflow          | ✅     | ✅             | ✅        |

# Tenki Application level access (https://tenki.cloud/docs/github/gh-app-access-level)

Review and understand what level of access each Tenki GitHub App requires on your GitHub Organization.

Tenki ships as **two separate GitHub Apps** that are installed independently:

* **Tenki Code Reviewer**, the AI-powered pull request review agent.
* **Tenki Runner**, the self-hosted GitHub Actions runner infrastructure.

Each app requests only the permissions it needs. If you only install Code Reviewer, you never grant Runner-level scopes, and vice versa. The sections below detail the exact permissions for each app.

## Tenki Code Reviewer permissions

The Code Reviewer app needs read access to your code and the ability to post review comments on pull requests. It does **not** request the `Administration` permission.

This scope is comparable to other AI code review tools (such as CodeRabbit or Greptile) and is limited to repository content and pull request interactions.

| Permission    | Access       | Why it's required                                                               |
| ------------- | ------------ | ------------------------------------------------------------------------------- |
| Metadata      | Read         | Enumerate repositories and basic organization info so the app can be installed. |
| Pull requests | Read & Write | Read pull request diffs for analysis and post review comments and summaries.    |
| Contents      | Read         | Read source files referenced in pull requests to provide contextual reviews.    |

## Tenki Runner permissions

The Runner app manages the lifecycle of self-hosted runners registered to your GitHub Organization. It requires broader permissions because GitHub's API mandates them for runner registration and workflow orchestration.

| Permission     | Access       | Why it's required                                                                                                                                                                                                                                                                                                                                                                                  |
| -------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Metadata       | Read         | Enumerate repositories, workflows, and runs for monitoring and job routing.                                                                                                                                                                                                                                                                                                                        |
| Members        | Read         | List organization members to map Tenki workspace users to GitHub identities.                                                                                                                                                                                                                                                                                                                       |
| Actions        | Read & Write | Read workflow runs and jobs, and trigger or cancel runs during runner management.                                                                                                                                                                                                                                                                                                                  |
| Contents       | Read & Write | Used by the migration wizard to generate a pull request with the necessary workflow file changes.                                                                                                                                                                                                                                                                                                  |
| Pull requests  | Read & Write | Used by the migration wizard to open a pull request containing the updated workflow files.                                                                                                                                                                                                                                                                                                         |
| Workflows      | Read & Write | Read and update workflow configuration files (`.github/workflows/`) during migration.                                                                                                                                                                                                                                                                                                              |
| Administration | Read & Write | Register and remove self-hosted runners at the organization level. GitHub's REST API requires this scope to call the [Create a registration token for an organization](https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-a-registration-token-for-an-organization) endpoint, there is no alternative API path for org-level runner registration without it. |

> **Questions?:** If you have any questions about these permissions, feel free to email us at hello@tenki.cloud.

# Connect your GitHub Organization (https://tenki.cloud/docs/github/gh-organization)

How to connect and update your GitHub Organization with your Tenki Workspace.

The connection between your GitHub Organization and your Tenki workspace is managed through the Tenki GitHub Application, which is responsible for creating and maintaining the link between both systems. You can install it using one of the following two methods:

## 1. Install the Tenki GitHub App during the onboarding

During new account onboarding, we walk you through each step, including installing the GitHub application. From here, click Connect GitHub to continue.

![GitHubApplicationInstall](https://tenki.cloud/images/get-started/connect-github.png)

Then select the level of permissions you want to grant the application and click on Install & Authorize:

![TenkiGithubInstall2](https://tenki.cloud/images/get-started/install-github.png)

[Video](https://storage.googleapis.com/tenki-cloud-assets/docs/tenki_step2_install_gh_app.mp4)

> **Important:** A Tenki Workspace can be connected to only one GitHub Organization and vice-versa.

## 2. Install the Tenki GitHub App manually

If you don't want to use the automatic onboard or prefer to install the application on your own you need to do it as below:

**Step 1:**
### Select your Workspace and Project

Verify that you’ve selected the correct workspace, then select your project.

![ManualGitHubApplicationInstallationStep1](https://tenki.cloud/images/get-started/manual-gh-install-step1.png)

**Step 2:**
### Access the Organization tab

Now within the Runners section click on the Organization tab and then click on the Connect GitHub button

![ManualGitHubApplicationInstallationStep2](https://tenki.cloud/images/get-started/manual-gh-install-step2.png)

**Step 3:**
### Application installation

You’ll see a modal displaying all your workspaces and the GitHub Organizations they are linked to. This helps ensure a unique connection, as each GitHub Organization can be connected to only one Tenki workspace.

Below is an example of how this looks after you’ve created a second workspace. If you only have one workspace, the Other workspaces you have access to section will be empty.

You can click on continue:

![ManualGitHubApplicationInstallationStep4](https://tenki.cloud/images/get-started/manual-gh-install-step4.png)

Select your GitHub user:

![ManualGitHubApplicationInstallationStep5](https://tenki.cloud/images/get-started/manual-gh-install-step5.png)

Select your GitHub Organization:

> **Info:** If you see Configure, it means the Tenki GitHub Application is already installed.

![ManualGitHubApplicationInstallationStep6](https://tenki.cloud/images/get-started/manual-gh-install-step6.png)

Select the level of access you want to provide and click on Install & Authorize:

![ManualGitHubApplicationInstallationStep7](https://tenki.cloud/images/get-started/manual-gh-install-step7.png)

**Step 4:**
### Verify the connection

After installation and authorization, simply verify that everything is set up correctly. Then navigate back to the Organization tab, where you should see your GitHub Organization successfully connected.

![ManualGitHubApplicationInstallationStep8](https://tenki.cloud/images/get-started/manual-gh-install-step8.png)

![GH-app-manual-install](https://tenki.cloud/images/get-started/manual-gh-install-step4.png)

## 3. When you're not owner of the GitHub Organization

When you try to install the Tenki GitHub Application on an organization where you’re not an owner, the process is slightly different. Instead of installing the application directly, you submit a request for installation.

You’ll be prompted to confirm the request, after which the organization owners will be notified. They can review and approve the installation from the GitHub UI. Once an administrator approves the request, the installation is completed and the connection proceeds automatically.

## Maintain/Update the connection

Whenever you need to review access levels or add or remove repositories, go to the Organization tab and click Configure Connection:

![GitHubApplicationMaintenance1](https://tenki.cloud/images/get-started/gh-link-maintenance-1.png)

You’ll be redirected to the GitHub interface, where you can manage which repositories the application has access to:

![GitHubApplicationMaintenance2](https://tenki.cloud/images/get-started/gh-link-maintenance-2.png)

> **Note:** The next section provides more details on linking and managing your repositories in Tenki.

# Manage your GitHub Repositories (https://tenki.cloud/docs/github/repo-management)

Connect, update, or remove GitHub repositories available to a Tenki project.

The connection between Tenki and your GitHub Organization is managed by the Tenki GitHub Application. From there, you define the level of access you grant, including which repositories Tenki can access.

This access is used to link repositories to your Tenki workspace:

* If you grant access to all repositories, Tenki will automatically have access to both existing repositories and any new ones created in the future.
* If you choose to limit access to a selected set of repositories, you can manage this directly from the GitHub UI, and any changes will be automatically reflected in your Tenki workspace and projects.

![AllRepositoryLevelAccess](https://tenki.cloud/images/get-started/gh-link-maintenance-2.png)

## Repository access: All repositories

Everything is handled automatically by the application.

Any repository created, updated, or deleted in the GitHub Organization connected to your Tenki workspace is automatically reflected in the Organization tab. No manual action is required, everything stays in sync automatically.

![SelectedRepositoryLevelAccess](https://tenki.cloud/images/get-started/gh-links-repos.png)

## Repository access: Selected repositories

When repository access is set to Selected repositories, the Tenki workspace can access only those specific repositories.

Any changes you make in GitHub: adding or removing repositories, theses changes are automatically applied to Tenki.

![AllRepositoryLevelAccess](https://tenki.cloud/images/get-started/selected-repo-links.png)

# Custom Context (https://tenki.cloud/docs/reviewer/custom-context)

Custom Context allows you to define repository-specific rules, expectations, and team preferences for the agent.

![TenkiCodeReviewerCustomContext](https://tenki.cloud/images/reviewer/custom-context.png)

For each repository, Tenki Reviewer can use a configuration file to define custom rules and specific settings.

This file provides persistent guidance that Tenki Code Reviewer applies to every review in that repository.

Manually create the `.md` file and save it in your codebase. Then, add its path to the Custom Context Panel so it can be applied to the selected repository.

![TenkiCodeReviewerCustomContext](https://tenki.cloud/images/reviewer/tcr-custom-context.png)

The Custom Context file is intentionally flexible. You can include **any instructions you want the agent to consistently apply**, for example:

* **Team rules you always want reviewed:** Coding standards, security requirements, architectural constraints, or internal best practices.
* **Areas to focus on:** Critical paths, high-risk modules, legacy code, or performance-sensitive components.
* **Things to ignore:** Generated files, vendor code, migrations, or any changes you don’t want reviewed.
* **Project-specific guidance:** Domain assumptions, business rules, or constraints that are unique to your product.

## Example

A Custom Context file is plain Markdown. Keep it focused and concrete, since the agent applies it on every review, so clear, specific rules produce the most consistent results:

```md
# Review context for our API service

## Always flag

- Endpoints that touch user data but don't check authorization
- New environment variables that aren't documented in `README.md`
- SQL built with string interpolation instead of parameterized queries

## Focus areas

- `src/billing/**` is high-risk; review pricing and rounding logic carefully
- Public API handlers in `src/api/**` must keep backward compatibility

## Ignore

- `**/*.generated.ts` and other generated output
- Lockfiles (`pnpm-lock.yaml`, `package-lock.json`)
- Snapshot test fixtures

## Conventions

- We use Conventional Commits; call out PR titles that don't follow it
- Prefer early returns over nested conditionals
```

## Best practices

* **Be specific.** "Flag missing authorization checks on user-data endpoints" guides the reviewer far better than "be careful about security."
* **Point to paths.** Naming directories (`src/billing/**`) lets the agent weight high-risk areas appropriately.
* **State what to ignore.** Explicitly excluding generated files and lockfiles keeps reviews signal-dense and avoids wasting the context window.
* **Keep it current.** Treat the file like code, updating it as your standards evolve so reviews stay aligned with how your team actually works.

## Frequently asked questions

**Where does the file live?**
Anywhere in your repository. Create the Markdown file, commit it, then add its path in the Custom Context Panel for that repository.

**Can each repository have different context?**
Yes. Custom Context is configured per repository, so every project can carry its own rules, focus areas, and exclusions.

**Does Custom Context replace the default review?**
No. It layers your repository-specific guidance on top of Tenki's standard bug, security, and quality checks; it doesn't turn them off.

# Quickstart (https://tenki.cloud/docs/reviewer/quickstart)

Set up Tenki Code Reviewer in minutes. Install the GitHub App and supercharge your workflows with the step-by-step Migration Wizard.

**Step 1:**
## Create your Tenki Account

To get started, head to the [Registration Page](https://app.tenki.cloud/auth/registration/). From there, choose Email and Password or Register with GitHub method:

![AccountCreation](https://tenki.cloud/images/get-started/account-creation.png)

**Step 2:**
## Access the Tenki Code Reviewer panel

Next step will be to select your project and access the Tenki Code Reviewer tab.

![TenkiCodeReviewStep1](https://tenki.cloud/images/get-started/tcr-step1.png)

**Step 3:**
## Install the Tenki Reviewer GitHub App

Next step will be to connect your GitHub Organization to your Workspace by installing the Tenki Reviewer GitHub application.

![TenkiCodeReviewStep2](https://tenki.cloud/images/get-started/tcr-step2.png)

![TenkiCodeReviewStep3](https://tenki.cloud/images/get-started/tcr-step3.png)

Select the level of permissions you want to
grant the application and click on Install & Authorize:

![TenkiCodeReviewStep4](https://tenki.cloud/images/get-started/tcr-step4.png)

**Step 4:**
## Create Your First PR Review

Perfect, you’re all set! 🎊. There are now two ways to trigger the Tenki Code Reviewer.

**When you open a PR, Tenki Code Reviewer posts two live comments simultaneously:**

1. Summary
2. Review Comment

**Both comments:**

* Appear as soon as analysis starts
* Update dynamically while the review is running
* Reach their final state when the 👍 icon appears

**Live Status**

| Status    | Emoji | Meaning                                                      |
| --------- | ----- | ------------------------------------------------------------ |
| Analyzing | 👀    | Tenki is building context and reviewing the PR (\~3 minutes) |
| Complete  | 👍    | Analysis finished                                            |
| Failed    | 😕    | Tag `@tenki-reviewer` to retry                               |

## Manual PR Review

You can trigger a code review manually by tagging `@tenki-reviewer` in a comment. This is especially useful for reviewing older PRs created before Tenki Code Reviewer was integrated.

![TenkiCodeReviewStep5](https://tenki.cloud/images/get-started/tcr-step5.png)

# Manage Your GitHub Application and Repositories (https://tenki.cloud/docs/reviewer/repo-management)

Connect and manage the GitHub repositories available to Tenki Code Reviewer in your workspace.

The connection between Tenki and your GitHub Organization is managed by the Tenki GitHub Application. From there, you define the level of access you grant, including which repositories Tenki can access.

This access is used to link repositories to your Tenki workspace:

* If you grant access to all repositories, Tenki will automatically have access to both existing repositories and any new ones created in the future.
* If you choose to limit access to a selected set of repositories, you can manage this directly from the GitHub UI, and any changes will be automatically reflected in your Tenki workspace and projects.

![AllRepositoryLevelAccess](https://tenki.cloud/images/get-started/gh-link-maintenance-reviewer-2.png)

## Repository access: All repositories

Everything is handled automatically by the application.

Any repository created, updated, or deleted in the GitHub Organization connected to your Tenki workspace is automatically reflected in the Organization tab. No manual action is required, everything stays in sync automatically.

![SelectedRepositoryLevelAccess](https://tenki.cloud/images/get-started/gh-links-repos-2.png)

## Repository access: Selected repositories

When repository access is set to Selected repositories, the Tenki workspace can access only those specific repositories.

Any changes you make in GitHub: adding or removing repositories, theses changes are automatically applied to Tenki.

![AllRepositoryLevelAccess](https://tenki.cloud/images/get-started/selected-repo-links-2.png)

## Choose which repositories get code review

The Code Reviewer agent only runs on repositories the Tenki GitHub App can access. Manage that list from GitHub:

**Step 1:**
Open your GitHub 

**Settings → Applications → Installed GitHub Apps**

.

**Step 2:**
Find 

**Tenki**

 in the list and click 

**Configure**

.

**Step 3:**
Under **Repository access**, choose **All repositories** or **Only select repositories** and adjust the selection.

**Step 4:**
Save. The reviewer-enabled repositories in your workspace update automatically; no action is needed inside Tenki.

## Frequently asked questions

**The reviewer isn't commenting on a repo. Why?**
The most common cause is that the repository isn't in the Tenki GitHub App's access list. Add it in GitHub (or switch to All repositories) and the change syncs automatically. See [Troubleshooting](https://tenki.cloud/docs/reviewer/troubleshooting.md) for more.

**Can I enable Code Reviewer on some repositories but not others?**
Yes. Use **Only select repositories** and include just the repos you want reviewed.

**Does changing access modify my GitHub repositories?**
No. Access controls only what Tenki can see; it never changes or deletes your repositories.

For the permissions the GitHub App requests, see [Tenki GitHub Application Access Levels](https://tenki.cloud/docs/github/gh-app-access-level.md).

# Review Anatomy (https://tenki.cloud/docs/reviewer/review-anatomy)

This page explains exactly how a Tenki review appears in your PR and how to interpret each component.

## Summary

The **Summary** is a high-level, decision-oriented overview of the PR.

It appears immediately and updates as the analysis progresses.

![TenkiCodeReviewerReviewAnatomy](https://tenki.cloud/images/reviewer/review-anatomy.png)

### Structure:

* What has been reviewed
* Findings grouped by severity
* Short recap of key issues
* Collapsed list of files reviewed
* Security risk assessment: An explicit security assessment of the PR. Only high-confidence, PR-fixable security issues are reported.
  * **LOW**, No security vulnerabilities identified
  * **MEDIUM**, Security edge cases introduced
  * **HIGH**, Exploitable vulnerabilities found

## Review Comment

The **Review Comment** contains the full breakdown of findings.

It appears at the same time as the Summary and updates live during analysis.

![TenkiCodeReviewerReviewComment2](https://tenki.cloud/images/reviewer/review-comment.png)

![TenkiCodeReviewerReviewComment2](https://tenki.cloud/images/reviewer/review-comment-2.png)

### Structure:

**Security**

* High / Medium / Low severity
* Includes explanations when applicable

**Code Quality**

* General code health assessment
* Structural or maintainability concerns

**Other Observations**

Additional relevant signals, such as:

* Performance risks
* Architectural concerns
* Notable patterns introduced
* Repeated anti-patterns

**Recommendation**

A single, clear outcome:

* **APPROVE**, Safe to merge
* **APPROVE with minor suggestions**, Non-blocking issues
* **CHANGES REQUESTED**, Blocking issues must be addressed

## Reporting Scope

Tenki only reports issues that:

* Are introduced by this PR
* Could cause bugs, security risks, or instability
* Can be addressed within the PR

# Manage your Code Reviewer seats (https://tenki.cloud/docs/reviewer/seat-management)

Control access to Code Reviewer by managing seats, assigning users, and adding more through billing.

Tenki Code Reviewer is billed at **$1.00 per review** — reviews are the unit of consumption, not seats. Seats control **who** on your team can trigger a review: each plan includes a fixed seat allowance (Starter up to 5, Team up to 50; see [Pricing](https://tenki.cloud/docs/pricing.md)), and only users assigned to a seat can run reviews automatically on PR open / update or manually via `@tenki-reviewer`.

This guide explains how to manage seats: how to assign, update, and remove them, and how to raise the seat allowance if your plan limit is too low for your team.

## Raise your seat allowance

If you need more seats than your current plan allows, go to the Billing Activity page:

![GetSeat1](https://tenki.cloud/images/get-started/get-seat-1.png)

Select Buy or Edit Subscription. You will be redirected to Stripe, where you can upgrade your plan or adjust your seat allowance. Reviews are still billed per review at $1.00 each — additional seats only raise the cap on who can trigger them.

![GetSeat2](https://tenki.cloud/images/get-started/get-seat-2.png)

![GetSeat3](https://tenki.cloud/images/get-started/get-seat-3.png)

## Seat Management

**Step 1:**
### Access the Seat Management page

To get started, go to the Seat Management page by selecting Settings and then the Code Reviewer tab. You should see the full table of

![SeatManagementStep0](https://tenki.cloud/images/get-started/seat-management-0.png)

**Step 2:**
### Assign a seat

All seats purchased through the billing system will appear here, ready to be assigned to GitHub users as shown below.

![SeatManagementStep2](https://tenki.cloud/images/get-started/seat-management2.png)

After clicking the Assign button, you’ll be prompted to enter a GitHub username. Once entered, confirm to complete the assignment.

![SeatManagementStep3](https://tenki.cloud/images/get-started/seat-management3.png)

The user will now be able to trigger the Code Reviewer automatically when opening a PR or manually by tagging
`@tenki-reviewer`.

**Step 3:**
### Manage assigned seats

To manage existing seats, whether to update, reassign, or remove a user, open the same table and click the Reassign or Unassign button.

![SeatManagementStep1](https://tenki.cloud/images/get-started/seat-management-1.png)

This works the same way as assigning a seat, just enter the GitHub user you want to grant access to.

![SeatManagementStep1-2](https://tenki.cloud/images/get-started/seat-management-1-2.png)

# Settings (https://tenki.cloud/docs/reviewer/settings)

Tenki Code Reviewer exposes a small set of configuration options to control when it runs and how much signal it produces.

![TenkiCodeReviewerSettings](https://tenki.cloud/images/reviewer/tcr-settings-2.png)

## Severity Threshold:

Controls which findings are surfaced in the review.

You can choose to include the following severity levels:

* **High**
* **Medium**
* **Low**

By default, only **High** severity findings are enabled.

Enabling additional levels will surface more detailed and verbose feedback, including non-blocking issues and minor observations.

**Use this when:**

* You want minimal, merge-blocking signal (High only)
* You want broader coverage during audits, refactors, or hardening phases

## Automatic Review

Controls **when the agent runs on a Pull Request**.

Available modes:

* **On**: runs on every PR update
* **Off**: runs only when the agent is explicitly mentioned or tagged in the PR

## Comment Detail Level

Controls **the level of verbosity** of the review.

Available modes:

* **Concise**: A brief overview of the vulnerabilities.
* **Standard**: The default option; provides a few sentences with enough detail about the issues or vulnerabilities detected.
* **Detailed**: The most comprehensive option; offers in-depth information about each issue or vulnerability found.

## Ignore Usernames

Allows excluding specific authors from automated reviews.

You can add one or more GitHub usernames to prevent Tenki Code Reviewer from running on PRs created by those users.

Common use cases:

* Bot or automation accounts
* Experimental or sandbox contributors
* Temporary exclusions during testing

# Troubleshooting (https://tenki.cloud/docs/reviewer/troubleshooting)

Diagnose Tenki Code Reviewer GitHub App access, review triggers, large pull requests, and repository settings.

If Tenki Code Reviewer isn't behaving as expected on a repository, the cause is almost always one of three things: the GitHub App can't access the repo, the pull request is too large for a single pass, or a setting is scoped differently than you expect. Work through the sections below in order; most issues are resolved by reinstalling or re-scoping the GitHub App.

## Tenki Code Reviewer does not respond to @tenki-reviewer

Tenki Code Reviewer uses the separate Tenki Reviewer GitHub App. It does not require a GitHub Actions workflow or a Tenki API key in repository secrets. Confirm that the Reviewer app can access the repository, then comment `@tenki-reviewer` on the open pull request. If the app is missing or its repository selection is stale, update or reinstall it from [Reviewer repository access](https://tenki.cloud/docs/reviewer/repo-management.md).

## Tenki Code Reviewer isn't running on a repository at all

If reviews never appear on a repo's pull requests, the repository is likely not accessible to Tenki. Confirm the repo is included in the Tenki GitHub App's access list, then reinstall the integration if needed. See [Enable Code Reviewer on GitHub Repositories](https://tenki.cloud/docs/reviewer/repo-management.md) for how repository access is granted and kept in sync.

## CI not running on Tenki’s commits

Ensure you’re using the GitHub App or custom app (not Actions user), check workflow triggers include the necessary events, and verify app permissions include CI triggers.

## "Context Window Exceeded" or Missing Files

The Pull Request is too large. Most AI models have a limit on the number of lines or files they can process in a single pass.
Break down large PRs into smaller, more manageable chunks.
Use an ignore list (e.g., .ai-ignore) to exclude auto-generated files, lockfiles (package-lock.json), or documentation.

## Reviews feel too noisy or miss the things you care about

Tenki Code Reviewer can be tuned per repository. If it's flagging things you don't care about, or missing your team's conventions, add a Custom Context file describing your standards, focus areas, and what to ignore. See [Custom Context](https://tenki.cloud/docs/reviewer/custom-context.md).

## Frequently asked questions

**Why did the reviewer skip my pull request?**
The most common causes are that the repository isn't connected (see [repository access](https://tenki.cloud/docs/reviewer/repo-management.md)) or the PR exceeded the model's context window. Splitting a very large PR into smaller ones usually resolves it.

**Can I control which files are reviewed?**
Yes. Use an ignore list to exclude generated files, lockfiles, and vendored code, and use [Custom Context](https://tenki.cloud/docs/reviewer/custom-context.md) to point the reviewer at high-risk areas.

**How do I re-run a review?**
Comment `@tenki-reviewer` on the open pull request.

Still stuck? Reach out to us at [hello@tenki.cloud](mailto:hello@tenki.cloud) or use the in-app chat (see image below).

![Tenki in-app support chat for Code Reviewer troubleshooting](https://tenki.cloud/images/reviewer/troubleshoot.png)

![Tenki support chat conversation](https://tenki.cloud/images/reviewer/fernand.png)

# Android Emulator (https://tenki.cloud/docs/runners/android-emulator)

Run Android emulator UI tests on Tenki Linux x64 Runners with nested virtualization (KVM) enabled.

Tenki Linux x64 Runners support **KVM nested virtualization**, so they can run Android emulator-based CI, Espresso, instrumented tests, screenshot tests, Detox, and similar UI-test workloads.

## Nested virtualization (KVM)

KVM is **available on request** for x64 runners. Once enabled on your workspace, your jobs can boot Android emulators using the standard Android SDK system images, including:

* `system-images;android-34;google_apis;x86_64`
* Older API levels (29 to 33) for legacy test matrices
* Google Play variants of the above

End-to-end UI tests (Espresso, instrumented JUnit, screenshot tests) run on the booted emulator within the runner.

> **Enable nested virtualization:** Email hello@tenki.cloud to enable KVM on your workspace. We'll confirm enablement within one business day.

## Example workflow

The workflow below uses [`reactivecircus/android-emulator-runner`](https://github.com/ReactiveCircus/android-emulator-runner) on a Tenki Linux runner. The only line that differs from a GitHub-hosted runner workflow is `runs-on`.

```yaml
jobs:
  ui-tests:
    runs-on: tenki-standard-large-8c-16g
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: 17

      - name: Cache AVD
        uses: actions/cache@v4
        with:
          path: |
            ~/.android/avd/*
            ~/.android/adb*
          key: avd-android-34

      - name: Run instrumented tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: 34
          target: google_apis
          arch: x86_64
          script: ./gradlew connectedCheck
```

## Picking a runner size

Android emulator workloads are memory-hungry and benefit from more cores during APK compilation. Recommended starting points:

| Workload                        | Recommended runner                  |
| ------------------------------- | ----------------------------------- |
| Single emulator, smoke tests    | `tenki-standard-medium-4c-8g`       |
| Mixed instrumented + unit suite | `tenki-standard-large-8c-16g`       |
| Sharded UI test matrix          | `tenki-standard-large-plus-16c-32g` |

See [Which Runner to use?](https://tenki.cloud/docs/runners/which-runner-should-i-use.md) for general sizing guidance.

## Caching the emulator

Use the Tenki cache (a drop-in replacement for `actions/cache`) to persist the AVD between runs. The first cold boot of a new API level takes a few minutes; subsequent runs with a warm AVD are much faster.

# Benchmarks (https://tenki.cloud/docs/runners/benchmarks)

Benchmark results and methodology comparing Tenki runners against GitHub-hosted runners across real open-source build workloads.

Tenki runners run on modern bare-metal hardware, so the same workflows finish faster than on the older VM instances GitHub Actions uses. Because the per-minute rate is lower too, moving to a larger runner often speeds up a build while still costing less. The numbers below compare identical workflows on Tenki and GitHub-hosted runners.

## How we benchmarked

* Tenki runner: `tenki-standard-medium-4c-8g` (4 vCPU, 8 GB RAM, bare-metal x64 Linux, one ephemeral VM per job).
* GitHub baseline: `ubuntu-latest` (2 vCPU, 7 GB RAM, GitHub-hosted Linux).
* Workflow parity: identical YAML on both sides, with only the `runs-on` value changed. No caching plugins, prebuilt images, or custom action substitutions.
* Cache state: warm. Each workload ran three consecutive times per runner, and the third run is reported.
* Sample size: 3 runs per workload per runner. The numbers below are the median of the warm-cache runs.
* Workloads: real, reproducible builds from public open-source projects (Rust, Docker, Node.js, Go, Android, n8n).
* Date range: April 2026, re-run quarterly.

## Results vs GitHub-hosted runners

| Workload                | GitHub-hosted | Tenki   | Delta      |
| ----------------------- | ------------- | ------- | ---------- |
| Rust `cargo build`      | 5s            | 3s      | 40% faster |
| Docker build            | 27s           | 19s     | 30% faster |
| Node.js `npm install`   | 10s           | 8s      | 20% faster |
| Go build                | 11s           | 0.1s    | 99% faster |
| Android `assembleDebug` | 1m 38s        | 1m 2s   | 37% faster |
| n8n monorepo (full CI)  | 55m 58s       | 29m 15s | 48% faster |

Raw logs and workflow files are open source. For a specific workload reproduction, write to [hello@tenki.cloud](mailto:hello@tenki.cloud).

## Cost

On common CI workloads Tenki runs the same jobs up to 60% cheaper than GitHub-hosted runners, billed per minute with no startup surcharge. See [the pricing page](https://tenki.cloud/pricing) for the full rate card across vCPU, memory, and macOS profiles.

# Limits, Concurrency & Cold Start (https://tenki.cloud/docs/runners/limits-and-concurrency)

Concurrency defaults per plan, cold start latency, queue handling, and scale-to-zero billing for Tenki Runners.

This page is the single reference for the operational limits of Tenki Runners, concurrency, cold start, queue handling, and how idle capacity is (not) billed.

## Cold start

Tenki Runners cold-start in approximately **15 seconds on average**, regardless of runner size or concurrency. There is no pool warm-up step; every job boots into a fresh VM.

## Concurrency defaults

Default concurrent-job limits, by plan:

| Plan       | Concurrent jobs               |
| ---------- | ----------------------------- |
| Starter    | Up to 5                       |
| Team       | Up to 50                      |
| Enterprise | Custom (unlimited on request) |

Higher concurrency is available on request at additional cost. Bursting beyond your default limit causes additional jobs to queue (not fail) until capacity frees up.

## Per-runner-family notes

| Runner family | Default concurrency on Team                                     |
| ------------- | --------------------------------------------------------------- |
| Linux x64     | 50                                                              |
| macOS M4 Pro  | 4 (Team default); higher macOS concurrency available on request |

Raising the macOS-specific cap is available on request; the overall account concurrency cap still applies.

## Queue handling

* Jobs that exceed your concurrency limit **queue**, not fail.
* Time spent in the queue is **not billed**, billing starts when the VM is assigned and the job begins running.

## Scale-to-zero billing

Tenki bills **per consumed minute**, rounded up to the next second on the last minute. There are **no idle charges**:

* You don't pay for weekends or overnight when nothing runs.
* You don't pay for a standby pool, there isn't one.
* VMs are destroyed immediately on job completion, so there's no post-job idle time.

The only recurring charge outside per-minute usage is your plan fee (Starter $0/mo, Team $200 to $250/mo) and any active add-ons. See [Pricing](https://tenki.cloud/docs/pricing.md) for the full breakdown.

## Cache size

GitHub Actions enforces a 10 GB-per-key cache size limit. Tenki does **not** apply additional storage limits or eviction policies on its side, cache entries remain available until you overwrite or delete them.

> **Need higher limits?:** If you regularly burst above 50 concurrent jobs or need a custom macOS concurrency profile, email hello@tenki.cloud and we'll provision it.

# macOS Runners (M4 Pro) (https://tenki.cloud/docs/runners/macos-runners)

Discover high-performance Apple Silicon (M4 Pro) macOS GitHub Actions runners built for faster CI, better reliability, and transparent per-minute pricing. The best macOS runners alternative for modern CI/CD workflows.

Tenki macOS Runners use **Apple Silicon M4 Pro** hardware and ship in four SKUs, so you can match the runner to your iOS / macOS / cross-platform workload. Every job runs in an **ephemeral VM destroyed at job end**, see [Security & Isolation](https://tenki.cloud/docs/trust/security.md) for the full model.

## SKUs and pricing

Pricing is **$0.025 per vCPU core per minute**.

| vCPU  | Memory | Disk  | Effective rate |
| ----- | ------ | ----- | -------------- |
| 2 CPU | 4 GB   | 10 GB | $0.05 / min    |
| 4 CPU | 8 GB   | 10 GB | $0.10 / min    |
| 6 CPU | 16 GB  | 10 GB | $0.15 / min    |
| 8 CPU | 32 GB  | 10 GB | $0.20 / min    |

See [Pricing](https://tenki.cloud/docs/pricing.md) for plan-level credits and add-ons.

> **Generally available:** macOS runners are generally available on all plans. Create a Tenki account, connect your GitHub organization, and you can start sending macOS workflows to Tenki immediately.

## Concurrency

By default we enable **4 concurrent macOS jobs** on the Team plan. Additional macOS concurrency is available on request. See [Limits, Concurrency & Cold Start](https://tenki.cloud/docs/runners/limits-and-concurrency.md) for the full reference.

## Image

The default macOS image is based on **macOS 15 Sequoia**. For Xcode version pinning, per-chip labels, parallel Xcode availability, custom images, and Docker-on-macOS, see [macOS Xcode & Custom Images](https://tenki.cloud/docs/runners/macos-xcode-and-images.md).

## Common workloads

* iOS app builds and Xcode test suites (XCTest, XCUITest)
* macOS app builds and notarisation
* React Native / Flutter / Unity iOS builds
* fastlane release pipelines with code signing

# macOS Xcode & Custom Images (https://tenki.cloud/docs/runners/macos-xcode-and-images)

Xcode version policy, custom macOS images, per-chip pinning, and Docker-on-macOS support for Tenki macOS Runners.

This page covers everything Xcode- and image-related on Tenki macOS Runners: what's on the default image, how to pin a specific Xcode version, how custom images work, and how to pull private Docker images from inside a macOS job.

## Default image

Tenki macOS Runners use a single base image based on **macOS 15 Sequoia**. The image ships with the toolchain we recommend for the majority of iOS / macOS / cross-platform workloads.

If your workflow needs something the default image doesn't ship, we have two paths: **custom labels** (preinstalled toolchain) and **custom images** (your full image, baked by us). Both are available to customers with committed capacity.

## Custom Xcode versions and per-chip pinning

Need to pin to a specific Xcode (e.g. `xcode-26`, `xcode-18`) or a specific chip generation? We can expose:

* **Per-toolchain labels** (e.g. `tenki-macos-xcode-26`) so workflows can pin to a known Xcode version in `runs-on:`.
* **Per-chip / per-SKU labels** so workflows can target a specific Apple Silicon generation when needed.
* **Parallel availability** of older Xcode versions alongside the latest, so you can roll Xcode forward at your own cadence.

These are scoped during onboarding and require committed capacity, they're a fit for teams who already know their target labels and concurrency profile.

> **Need custom labels?:** Talk to us at hello@tenki.cloud. We'll work with your team to bake the labels you need as you scale with us.

## Custom images

For teams whose iOS / Unity / cross-platform pipelines need a fully custom macOS image, proprietary tooling, internal SDKs, specific Xcode + simulator combinations, we can deploy your image to our fabric.

The custom-image path uses our standard build system (Packer-based, VM compatible) and is available for both Linux x64 and macOS. Custom images are scoped during onboarding and tied to committed capacity.

## Docker on macOS

Yes, a Tenki macOS Runner can pull a Docker image from a **private container registry** you operate. This is a common pattern for Unity iOS pipelines and cross-platform jobs that bundle native dependencies into a container.

You authenticate to your private registry the same way you would on any macOS runner (for example, `docker login` with credentials from GitHub Actions secrets), then pull and run as usual.

## Image refresh cadence

When Apple ships a new Xcode (or an App Store submission cutoff lands), we work with custom-image / custom-label customers to schedule the rollout. Older Xcode versions remain available in parallel as long as your team needs them, we do not retire a version without prior agreement.

If you're on the default image and need an Xcode bump fast, email [hello@tenki.cloud](mailto:hello@tenki.cloud) and we'll prioritize the refresh.

# Networking & Egress (https://tenki.cloud/docs/runners/networking)

How Tenki Runners handle egress traffic, shared vs. dedicated IP ranges, and private connectivity options for your CI workloads.

This page describes how Tenki Runners reach the public internet, what egress IP guarantees we offer, and what's possible for private connectivity into your own cloud accounts.

## Egress IPs

Tenki operates a **dedicated public subnet**, a fixed CIDR that all Tenki Runner traffic egresses from. By default, the range is shared across all tenants on the fabric, with multiple runners sharing a single egress IP through NAT.

This means:

* If you need to allowlist Tenki traffic in your downstream services, you can allowlist our published shared egress range.
* Multiple runners can share a single IP simultaneously, this is the default behaviour.
* The egress range is fixed; it does not rotate without prior notice.

## Dedicated IP allocation

If you require a dedicated IP block, for example to allowlist *only your* CI traffic in a partner's firewall, we can sub-allocate a range to your workspace.

* **Price:** $100 per IP per month
* **Control:** With a dedicated allocation you control how your runners map to IPs within the assigned range.

Contact [hello@tenki.cloud](mailto:hello@tenki.cloud) to scope a dedicated allocation.

## Private connectivity (PrivateLink, VPC peering)

AWS PrivateLink and VPC peering are not currently configured on our fabric.

That said, our network is built on **EVPN/VXLAN across a spine-leaf architecture**, which can support private L2/L3 extension. If private connectivity into your AWS (or other cloud) account is a hard requirement for your evaluation, we're happy to scope the work.

> **Private networking required?:** Reach out at hello@tenki.cloud and describe the target VPC and connectivity model. We'll come back with a scoping estimate.

# Quickstart (https://tenki.cloud/docs/runners/quickstart)

Set up Tenki Runners in minutes. Install the GitHub App and supercharge your workflows with the step-by-step Migration Wizard.

**Step 1:**
## Create your Tenki account

Open the [Tenki registration page](https://app.tenki.cloud/auth/registration/) and register with email and password or GitHub.

![Tenki registration page with email and GitHub sign-up options](https://tenki.cloud/images/get-started/account-creation.png)

[Video](https://storage.googleapis.com/tenki-cloud-assets/docs/tenki_step_1_registration.mp4)

**Step 2:**
## Install the Tenki GitHub App

Open the [Tenki dashboard](https://app.tenki.cloud), choose the workspace and project you want to connect, select **Runners**, and start the GitHub connection. Install the Tenki Runners GitHub App for your organization:

![Tenki Runners dashboard prompting you to connect a GitHub organization](https://tenki.cloud/images/get-started/aiow-step1.png)

On GitHub, choose the repositories Tenki can access, then select **Install & Authorize**:

![GitHub installation page for selecting Tenki Runners repository access](https://tenki.cloud/images/get-started/github-install.png)

[Video](https://storage.googleapis.com/tenki-cloud-assets/docs/tenki_step2_install_gh_app.mp4)

> **Important:** A Tenki Workspace can be connected to only one GitHub Organization and vice-versa.

Choose one migration path: use the Migration Wizard (3A), or update the workflow manually (3B).

**Step 3A:**
## Migrate with the Migration Wizard (recommended)

In the Tenki Runners dashboard, open **Migration Wizard** and select the repository:

![Migration Wizard repository selection in the Tenki Runners dashboard](https://tenki.cloud/images/get-started/aiow-mw-1.png)

We'll detect your current runners automatically. Next, select the Tenki Runner you want to switch to:

![Migration Wizard showing detected GitHub-hosted runners and Tenki replacement options](https://tenki.cloud/images/get-started/aiow-mw-2.png)

Then we'll generate a pull request for you to review and merge.

![Migration Wizard previewing the pull request it will create](https://tenki.cloud/images/get-started/aiow-mw-3.png)

After you review and merge the pull request, the workflow runs on Tenki Runners.

![Tenki Runners dashboard showing a migrated workflow job](https://tenki.cloud/images/get-started/aiow-mw-4.png)

[Video](https://storage.googleapis.com/tenki-cloud-assets/docs/tenki_step3_migration_wizard.mp4)

**Step 3B:**
## Migrate the workflow manually

GitHub Actions use the `runs-on` field in workflow files (located in `.github/workflows`) to determine which runner to use.

After the repository is connected through the Tenki Runners GitHub App, the only workflow-file change is replacing the existing runner tag with a Tenki runner tag:

```yaml
jobs:
  build:
-    runs-on: ubuntu-latest
+    runs-on: tenki-standard-medium-4c-8g
```

Tenki currently offers the following configurations:

| **Instance Type**                 | **Compute** | **Memory** |
| --------------------------------- | ----------- | ---------- |
| tenki-standard-autoscale          | dynamic     | dynamic    |
| tenki-standard-small-2c-4g        | 2 vCPU      | 4 GB       |
| tenki-standard-medium-4c-8g       | 4 vCPU      | 8 GB       |
| tenki-standard-large-8c-16g       | 8 vCPU      | 16 GB      |
| tenki-standard-large-plus-16c-32g | 16 vCPU     | 32 GB      |

The Starter plan supports runner sizes up to 4 vCPU / 8 GB RAM. Larger sizes require Team or Enterprise; see [Pricing](https://tenki.cloud/docs/pricing.md).

> **Custom configuration ?:** Can't find the configuration you need? Reach out to us at hello@tenki.cloud, our team will be glad to create a custom solution tailored to your needs.

To make integration easier, we've added a dedicated view on the Runners page. From there, you can quickly copy the runner tag and paste it directly into your workflow file.

[Video](https://storage.googleapis.com/tenki-cloud-assets/docs/tenki_step3_manual_migration.mp4)

***

## Next steps

Once your first jobs are running on Tenki, common things to set up:

* [Limits, Concurrency & Cold Start](https://tenki.cloud/docs/runners/limits-and-concurrency.md), what to expect at peak load
* [Networking & Egress](https://tenki.cloud/docs/runners/networking.md), egress IPs and private connectivity
* [Secrets](https://tenki.cloud/docs/runners/secrets-and-signing.md), how Tenki handles GitHub Actions secrets
* [Android Emulator](https://tenki.cloud/docs/runners/android-emulator.md), KVM nested virtualization for UI tests
* [macOS Xcode & Custom Images](https://tenki.cloud/docs/runners/macos-xcode-and-images.md), Xcode pinning and custom images
* [Security & Isolation](https://tenki.cloud/docs/trust/security.md), ephemeral VMs and the isolation model

***

## Troubleshooting

Not seeing your organization in the Tenki dashboard? Here are a few things to check:

* The Tenki GitHub App isn't installed on your GitHub Organization. Make sure it's properly installed. (Settings > Applications > Installed GitHub Apps)
* Your GitHub user isn't a member of the organization. Double-check your access.
* If you selected `Only select repositories` during installation: Make sure you're pushing to a repository that's actually included in your selection. If not, you can update the list anytime from your GitHub settings.

Still stuck? Reach out to us at [hello@tenki.cloud](mailto:hello@tenki.cloud) and we'll be happy to help.

# Manage your GitHub Repositories (https://tenki.cloud/docs/runners/repo-management)

Connect and manage the GitHub repositories available to Tenki Runners in your workspace.

The connection between Tenki and your GitHub Organization is managed by the Tenki GitHub Application. From there, you define the level of access you grant, including which repositories Tenki can access.

This access is used to link repositories to your Tenki workspace:

* If you grant access to all repositories, Tenki will automatically have access to both existing repositories and any new ones created in the future.
* If you choose to limit access to a selected set of repositories, you can manage this directly from the GitHub UI, and any changes will be automatically reflected in your Tenki workspace and projects.

![AllRepositoryLevelAccess](https://tenki.cloud/images/get-started/gh-link-maintenance-2.png)

## Repository access: All repositories

Everything is handled automatically by the application.

Any repository created, updated, or deleted in the GitHub Organization connected to your Tenki workspace is automatically reflected in the Organization tab. No manual action is required.

![SelectedRepositoryLevelAccess](https://tenki.cloud/images/get-started/gh-links-repos.png)

## Repository access: Selected repositories

When repository access is set to Selected repositories, the Tenki workspace can access only those specific repositories.

Any changes you make in GitHub: adding or removing repositories, these changes are automatically applied to Tenki.

![AllRepositoryLevelAccess](https://tenki.cloud/images/get-started/selected-repo-links.png)

## Update which repositories Tenki can access

Repository access is always managed from GitHub, and Tenki reflects whatever you configure there:

**Step 1:**
Open your GitHub 

**Settings → Applications → Installed GitHub Apps**

.

**Step 2:**
Find 

**Tenki**

 in the list and click 

**Configure**

.

**Step 3:**
Under **Repository access**, choose **All repositories** or **Only select repositories** and adjust the selection.

**Step 4:**
Save. The change syncs to your Tenki workspace and projects automatically.

## Frequently asked questions

**Do I manage repository access in Tenki or in GitHub?**
In GitHub. The Tenki GitHub App is the source of truth, and your Tenki workspace mirrors it automatically.

**If I add a new repository, do I have to connect it manually?**
Only if you're on **Selected repositories**: add it to the app's list in GitHub. On **All repositories**, new repos appear automatically.

**Will removing a repository from Tenki affect my GitHub repo?**
No. Changing access only controls what Tenki can see; it never modifies or deletes your GitHub repositories.

For the access levels the GitHub App requests, see [Tenki GitHub Application Access Levels](https://tenki.cloud/docs/github/gh-app-access-level.md).

# Runner Images (https://tenki.cloud/docs/runners/runner-images)

What's preinstalled on Tenki Linux and macOS runner images, how we build them with Packer and VMs, and how to request custom images.

This page describes what's on a Tenki runner image out of the box, how we build them, and how custom images work.

## Linux x64 default image

Tenki Linux x64 runners use the **official GitHub Actions runner images** maintained at [`actions/runner-images`](https://github.com/actions/runner-images). The default image is **Ubuntu 24.04**.

Practical consequence: anything that runs on GitHub-hosted `ubuntu-latest` runs on Tenki Linux runners with no changes. The toolchains (Node, Python, Ruby, Java, Go, Rust, Docker, gcloud, AWS CLI, fastlane, Android SDK + NDK, etc.) are identical to GitHub's, on the same version cadence.

## macOS default image

Tenki macOS Runners use a curated image based on **macOS 15 Sequoia** with the toolchain we recommend for iOS, macOS app, and cross-platform builds.

For Xcode version pinning, parallel Xcode availability, or fully custom macOS images, see [macOS Xcode & Custom Images](https://tenki.cloud/docs/runners/macos-xcode-and-images.md).

## How we build images

Both Linux and macOS images are built with **Packer** and run as **VM-based** images on our fabric. Internal customers (and now external) benefit from:

* Reproducible image builds
* Fast cold boot ([\~15 seconds](https://tenki.cloud/docs/runners/limits-and-concurrency.md#cold-start))
* Predictable image refresh cadence

## Custom images

We support fully custom images for both Linux x64 and macOS. The typical use cases:

* Internal SDKs, proprietary tooling, or licensed dependencies that can't live in a public registry
* A specific Xcode / simulator matrix that needs to be locked in
* Pre-warmed caches for very large monorepos

Custom images are scoped during onboarding and tied to committed capacity. Contact [hello@tenki.cloud](mailto:hello@tenki.cloud) to start the conversation.

> **What's on the image today?:** If you want the exact tool/version list before migrating, email hello@tenki.cloud, we'll send the current manifest.

# Secrets (https://tenki.cloud/docs/runners/secrets-and-signing)

How Tenki Runners handle secrets and why we use GitHub Actions secrets directly.

Tenki does **not** operate a secrets store. All secrets used in your workflows live in **GitHub Actions secrets** (repo, environment, or organization) and are injected into the job at runtime through the standard `secrets.*` mechanism.

This page explains why.

## The model

* You store secrets in GitHub Actions (or in your own secret manager pulled in at job-time).
* Tenki provisions a fresh VM for the job.
* GitHub passes the secret values into the runner environment as usual.
* The VM, including any cached secret material, is **destroyed when the job ends**.

Because the VM is single-use (see [Security & Isolation](https://tenki.cloud/docs/trust/security.md)), there is no persistent state where secret material could leak between jobs.

## Why we don't run our own secrets store

Two reasons:

1. **Smaller blast radius.** The fewer places your secrets live, the better. Re-using GitHub's secret store keeps the surface area to systems you already audit and trust.
2. **No vendor lock-in.** Your workflows remain identical to vanilla GitHub Actions. Migrating to or from Tenki does not require re-keying anything.

See [Security & Isolation](https://tenki.cloud/docs/trust/security.md) for the full model.

## Using secrets in a workflow

Because Tenki uses GitHub Actions secrets natively, referencing them looks exactly like it does on GitHub-hosted runners; only the `runs-on` value changes:

```yaml
jobs:
  deploy:
    runs-on: tenki-standard-small-2c-4g
    steps:
      - uses: actions/checkout@v4
      - name: Deploy
        env:
          API_TOKEN: ${{ secrets.API_TOKEN }}
        run: ./scripts/deploy.sh
```

GitHub injects `secrets.API_TOKEN` into the job at runtime and automatically masks the value in logs. When the job finishes, the VM (and any secret material it held in memory) is destroyed.

## Bringing your own secret manager

If your secrets live in an external manager (such as HashiCorp Vault, AWS Secrets Manager, or GCP Secret Manager), nothing changes on Tenki. Authenticate to that provider inside the job, typically using a single GitHub Actions secret or OIDC, and pull the rest at runtime, exactly as you would on GitHub-hosted runners. The fetched values exist only for the lifetime of the ephemeral VM.

## Frequently asked questions

**Does Tenki store or log my secrets?**
No. Tenki does not operate a secrets store, and secret values are masked in logs by GitHub. They exist only in the ephemeral VM for the duration of the job.

**Can secrets leak between jobs?**
No. Every job runs in a fresh, single-use VM that is destroyed when the job ends, so there's no persistent state shared between jobs.

**Do I need to re-key my secrets when migrating to Tenki?**
No. Your workflows and `secrets.*` references stay identical; only the `runs-on` label changes.

# Troubleshooting (https://tenki.cloud/docs/runners/troubleshooting)

Reach out to us at hello@tenki.cloud and we'll be happy to help.

This page collects the most common issues teams hit when setting up Tenki Runners, along with the fastest way to resolve each one. If you're still blocked after working through the relevant section, we're one email away.

## My organization isn't showing up in Tenki

Not seeing your organization in the Tenki dashboard? Here are a few things to check:

* The Tenki GitHub App isn't installed on your GitHub Organization. Make sure it's properly installed. (Settings > Applications > Installed GitHub Apps)
* Your GitHub user isn't a member of the organization. Double-check your access.
* If you selected `Only select repositories` during installation: Make sure you're pushing to a repository that's actually included in your selection. If not, you can update the list anytime from your GitHub settings. See [Manage your GitHub Repositories](https://tenki.cloud/docs/runners/repo-management.md) for how access stays in sync.

## My jobs are stuck as "queued" or never start

When a job stays queued and never picks up a Tenki runner, it's almost always a label or capacity issue:

* **The `runs-on` label doesn't match a Tenki runner.** Confirm your workflow targets a valid Tenki label (for example `tenki-standard-small-2c-4g`). See [Which runner should I use?](https://tenki.cloud/docs/runners/which-runner-should-i-use.md) for the full list of available sizes.
* **You've hit your plan's concurrency limit.** Jobs above your concurrent-job ceiling wait for a free slot. Review [Limits & Concurrency](https://tenki.cloud/docs/runners/limits-and-concurrency.md) to see your current limits and how to raise them.
* **GitHub Actions is disabled for the repository.** Check **Settings → Actions → General** and ensure Actions are allowed.

## My build runs out of memory or is slower than expected

* If a job is killed or thrashes, it likely needs a larger runner. Pick a size with more vCPU/RAM. See [Which runner should I use?](https://tenki.cloud/docs/runners/which-runner-should-i-use.md) and [Linux x64 Runners](https://tenki.cloud/docs/runners/x64-runners.md).
* First-run cold starts and cache behavior are covered in [Limits & Concurrency](https://tenki.cloud/docs/runners/limits-and-concurrency.md). Warm caches significantly reduce repeat-build times.

## Frequently asked questions

**Do I need to change my workflow files to use Tenki?**
No. Tenki is a drop-in replacement for GitHub-hosted runners; you only change the `runs-on` value. Everything else in your workflow stays the same.

**Will switching runner size break my pipeline?**
No. Runner size only affects the compute allocated to the job; your steps and commands are unchanged.

**A repository is missing from Tenki. What do I do?**
Confirm the repo is included in the Tenki GitHub App's repository access list. Changes you make in GitHub sync automatically. See [Manage your GitHub Repositories](https://tenki.cloud/docs/runners/repo-management.md).

Still stuck? Reach out to us at [**hello@tenki.cloud**](mailto:hello@tenki.cloud) and we'll be happy to help.

# Which Runner to use? (https://tenki.cloud/docs/runners/which-runner-should-i-use)

Learn which GitHub Actions runner CPU cores and memory combinations to use for each CI workload. Optimize performance and costs with the right runner specs.

Choosing the right runner is one of the simplest ways to improve CI performance, reliability, and cost efficiency. Yet it's often treated as a guess: "bigger runner = faster pipeline".

In reality, there is no universally "best" runner. The best runner is the one whose CPU and memory profile matches the way your jobs actually run.

This page explains how to choose the right Tenki runner for your workload, based on how CPU cores and memory affect different types of GitHub Actions jobs.

## The core principle: performance depends on your bottleneck

Every CI job is constrained by something:

* CPU
* Memory
* Parallelism
* Startup time
* I/O

Runner performance improves only when you scale the resource that is limiting your job. Adding more of the wrong resource increases cost without reducing execution time.

Before choosing a runner, ask one simple question:

> What is slowing my job down right now?

## How CPU cores affect CI performance

CPU cores determine how much work can happen at the same time.

More cores improve performance when:

* Tasks can run in parallel
* The tooling supports concurrency

Common CPU-bound workloads

* Compiling large codebases (C/C++, Rust, Go)
* Java or Kotlin builds with Gradle/Maven parallel workers
* Test suites that shard or run concurrently
* Pipelines with multiple independent build steps

### Rule of thumb

If your job can execute multiple tasks simultaneously, more cores will reduce total runtime.

When more cores don't help

* Single-threaded scripts
* Sequential pipelines
* Jobs waiting on network or I/O

In these cases, increasing CPU cores won't make jobs faster, it only increases runner cost.

## How memory impacts CI stability and speed

Memory affects how reliably and predictably jobs run.

More memory helps when:

* Large dependency trees are loaded into RAM
* Tools rely heavily on caching
* Multiple processes run at the same time

Memory-intensive workloads

* Node.js builds (npm, pnpm, Yarn)
* Frontend builds (Webpack, Vite, Next.js)
* JVM-based applications
* Docker image builds
* Integration and end-to-end tests

### Rule of thumb

CPU makes jobs faster.
Memory prevents jobs from being slow.

Insufficient memory leads to:

* Random slowdowns
* Out-of-memory errors
* Process restarts
* Flaky pipelines

Adding memory won't speed up a CPU-bound job, but too little memory can slow down any job.

## CPU vs memory: common CI workload profiles

### Lightweight jobs (linting, formatting, scripts)

ESLint, Prettier, Shell scripts, Static analysis etc..

Best runner

* Small runners: `tenki-standard-small-2c-4g`
* Low core count, minimal memory

Why

* Startup time matters more than raw power
* Over-provisioning wastes resources

### Build-heavy jobs (compilation, asset bundling)

Large backend builds, Frontend production builds, Monorepos

Best runner

* Higher core count: `tenki-standard-large-8c-16g`/`tenki-standard-large-plus-16c-32g`

Why

* Enough memory to avoid swapping
* Builds scale well with parallelism
* Memory ensures consistent performance

### Test-heavy jobs (unit, integration, E2E)

Jest, PyTest, JUnit, Cypress, Playwright, Service-based test suites etc..

Best runner

* Balanced CPU and memory: `tenki-standard-medium-4c-8g`/`tenki-standard-large-8c-16g`

Why

* Tests benefit from parallel execution
* Multiple processes consume RAM quickly

### Docker and container workflows

Docker builds, Multi-stage images, Layer caching

Best runner

* Memory-optimized runners: `tenki-standard-large-plus-16c-32g`

Why

* Docker builds consume significant memory
* Filesystem operations benefit from RAM

### Data processing and analytics

ETL jobs, Large dataset validation, ML preprocessing

Best runner

* High-memory runner: `tenki-standard-large-plus-16c-32g`

Why

* Dataset size is the primary bottleneck
* CPU is secondary to memory availability

## A practical way to choose the right Tenki runner

If you're unsure where to start, follow this approach:

1. Start with the smallest runner that supports your job
2. Observe:

* Job duration
* Failures or retries
* Variability between runs

3. Increase CPU cores if jobs are consistently slow
4. Increase memory if jobs are unstable or flaky
5. Optimize costs by matching runner size to workload type

This way you improve performance without adding unnecessary cost.

## Final takeaway

There is no single "best" runner.

The right runner depends on:

* How parallel your job is
* How much memory your tools consume
* Whether performance or cost is your priority

By aligning runner resources with workload behavior, Tenki helps you achieve:

* Faster GitHub Actions pipelines
* More predictable CI runs
* Better cost-to-performance ratios

Choosing the right runner means matching runner size to the workload rather than always using a larger one.

# Linux x64 Runners (https://tenki.cloud/docs/runners/x64-runners)

Browse Tenki Cloud's range of x64 Runners with various CPU and memory configurations. Find the perfect performance tier for your workflow needs from 2 to 16 vCPUs.

Tenki's x64 Standard Runners use 4th Gen AMD EPYC processors with a 1:2 physical-to-virtual core mapping. Each pair of x64 vCPUs corresponds to a single physical core, which keeps compute performance consistent and predictable.

This mapping gives predictable resource utilization and price-performance for CI workloads and ephemeral compute tasks.

> **Important:** We've changed the default version of our runners image to Ubuntu 24.04.

| **Runner Offering**               | **Compute** | **Memory** |
| --------------------------------- | ----------- | ---------- |
| tenki-standard-small-2c-4g        | 2 CPU       | 4 GB       |
| tenki-standard-medium-4c-8g       | 4 CPU       | 8 GB       |
| tenki-standard-large-8c-16g       | 8 CPU       | 16 GB      |
| tenki-standard-large-plus-16c-32g | 16 CPU      | 32 GB      |

> **Need more compute?:** Additional and larger runners are available on the Team plan. Email hello@tenki.cloud and we'll provision them for your workspace.

### Concurrency

The default concurrent-job limit depends on your plan, see [Limits, Concurrency & Cold Start](https://tenki.cloud/docs/runners/limits-and-concurrency.md) for the full reference. Higher concurrency is available on request.

### Image

Tenki uses the official GitHub Actions runner images for AMD runners, available at [`actions/runner-images`](https://github.com/actions/runner-images), so anything that runs on GitHub Actions Linux runners also runs on Tenki. For the full image story (Linux + macOS + custom builds), see [Runner Images](https://tenki.cloud/docs/runners/runner-images.md).

### Nested virtualization (KVM)

KVM nested virtualization can be enabled on x64 runners on request. This is the configuration you want for **Android emulator workloads** (Espresso, instrumented UI tests), see [Android Emulator](https://tenki.cloud/docs/runners/android-emulator.md) for a full example and recommended runner sizes.

### Custom image

We support custom images. To get your image deployed to our fabric, contact us at [hello@tenki.cloud](mailto:hello@tenki.cloud), see [Runner Images](https://tenki.cloud/docs/runners/runner-images.md) for the full custom-image story.

# Sandbox ADE (https://tenki.cloud/docs/sandbox/ade)

Download the Sandbox ADE, a desktop app for macOS and Linux that runs coding agents like Claude Code, Codex, and Pi inside isolated Linux VMs.

The Sandbox ADE (Agentic Development Environment) is a native desktop app for macOS and Linux that runs coding agents inside Tenki Sandbox VMs. Start a chat, hand a task to an agent, and it runs inside a disposable Linux VM with root access, while your own machine is left alone.

![Tenki Sandbox ADE: parallel agent chats with live diffs and a change review panel](https://tenki.cloud/images/marketing/sandbox-demo.png)

Coding agents are most useful when they can run real commands, which is also the point at which they can do real damage. Rather than give an agent root on your laptop, the ADE gives each task its own Linux VM, shows you everything the agent does inside it, and prompts for permission before risky actions.

If you'd rather drive sandboxes from code or a terminal, use the [SDK or CLI](https://tenki.cloud/docs/sandbox/quickstart.md). All surfaces talk to the same VMs.

## Download and install

| Platform                  | Package     | Download                                                                      |
| ------------------------- | ----------- | ----------------------------------------------------------------------------- |
| macOS (Apple silicon)     | `.dmg`      | [Download for macOS](https://tenki.cloud/api/download?platform=mac)           |
| Linux x64 (Debian/Ubuntu) | `.deb`      | [Download .deb](https://tenki.cloud/api/download?platform=linux-deb)          |
| Linux x64 (AppImage)      | `.AppImage` | [Download AppImage](https://tenki.cloud/api/download?platform=linux-appimage) |

There is nothing else to install locally. You do not need Docker or a local virtualization stack, because sandboxes run in Tenki Cloud; the app only needs network access and `git` on your machine. The GitHub CLI (`gh`) is optional but recommended for pull-request flows.

## First launch

Setup takes about two minutes:

1. **Sign in to Tenki Cloud.** Choose **Continue with Tenki Account** to authenticate in your browser, or paste a Tenki API key if you prefer. Browser sign-in asks you to choose a workspace when your account has more than one, then returns a credential bound to that workspace. No account yet? Sign-up is part of the same flow.
2. **Setup check.** The app verifies `git` is installed (required) and looks for the GitHub CLI (optional).
3. **Connect an agent.** Sign in to at least one agent provider (see the table below). You can add or change providers later in **Settings → Providers**.

## Supported agents

The ADE ships three agent harnesses. Each one signs in with the subscription you already have, or a provider API key:

| Agent           | Subscription sign-in                                   | API key alternative           |
| --------------- | ------------------------------------------------------ | ----------------------------- |
| **Claude Code** | Claude account (`claude` CLI login or a service token) | Anthropic API key             |
| **Codex**       | ChatGPT account (`codex login`)                        | OpenAI API key                |
| **Pi**          | Pi account                                             | Anthropic and OpenAI API keys |

Per chat, the composer toolbar lets you pick:

* **Model**: current models from each provider; picking a model selects its agent.
* **Effort**: reasoning level, where the model supports it.
* **Mode**: the agent's permission mode, from read-only and plan modes through "ask before risky actions" (the default) up to full auto-accept.

## Start a task

A new chat asks three things:

1. **Project and branch.** Pick a GitHub repository (add one with `Mod+Shift+O`) and the branch to start from, or no repo at all for a blank sandbox. The ADE clones the repo into the sandbox using your GitHub credentials.
2. **Where it runs.** **Cloud** (the default) creates a fresh sandbox VM for the chat. You can also run a chat locally, in a git worktree or directly in your local clone, when you explicitly want the agent on your machine instead of in a VM.
3. **Environment.** By default the sandbox boots from the [base image](https://tenki.cloud/docs/sandbox/base-image.md). Point it at a prepared environment instead (a pre-built image or a [snapshot](https://tenki.cloud/docs/sandbox/snapshots.md)), and customize the machine size (CPU, memory, disk). Repositories can save a default environment and size so new chats are one keystroke.

Then type the task and send. The agent works inside the VM as root, so it can install packages, run servers, and run whatever else the task needs, all without reaching your host machine.

> **One chat, one sandbox:** Every cloud chat owns exactly one sandbox session. Run several chats in parallel, each in its own isolated VM, and split the window into panes to watch them side by side.

## While the agent works

Everything the agent does streams into the chat as it happens: messages, thinking, file edits, shell commands, and tool calls.

![An agent working in the Sandbox ADE, with tool calls streaming into the chat and the change review panel open](https://tenki.cloud/images/docs/sandbox/ade-agent-working.png)

* **Permission prompts.** In the default mode, the agent stops and asks before risky tool calls. You approve once, always-allow for the session, or deny. Switch the mode per chat if you want plan-only, auto-accept edits, or full autonomy.
* **Review diffs** (`Mod+E`). A change review panel shows uncommitted and committed changes per file, with side-by-side or unified diffs and line comments you can send back to the agent.
* **Terminal** (`Mod+J`). A real shell inside the sandbox: inspect state, run commands, or fix things yourself while the agent works.
* **Files panel** (`Mod+G`) to browse and search the workspace.
* **Embedded browser.** Open the app the agent is building in a built-in browser pane. An annotate mode lets you click an element on the page and drop it, screenshot and styles included, straight into your next message.
* **Preview URLs.** Agents can expose a port from the sandbox and hand you a public preview URL for the dev server they just started.
* **Notifications.** Optional native notifications when an agent needs approval, errors, or finishes, with per-event toggles and a long-running-task threshold in Settings.

Because the agent runs in a disposable VM, a bad command such as an errant `rm -rf` or a prompt-injected curl-pipe-bash cannot reach anything outside the sandbox. Delete the session whenever you want and start a fresh one.

## Ship the result

Code leaves the sandbox through git, and you decide when. A context-aware button in each chat offers the next sensible step (**Commit**, **Commit & push**, or **Commit, push & create PR**) with AI-drafted commit messages and PR descriptions you can edit before they go out. The PR opens on GitHub in your browser.

## Session lifecycle and billing

ADE cloud chats are regular sandbox sessions. They show up in your workspace alongside sessions created through the CLI or SDKs, follow the same [lifecycle](https://tenki.cloud/docs/sandbox/sessions.md), and bill the same way; see [pricing](https://tenki.cloud/docs/pricing.md).

* **Reopen to resume.** The sandbox keeps running when you switch away or quit the app. Reopen a recent chat and the ADE reconnects to the same VM in seconds, with the full transcript restored.
* **Sessions auto-extend while in use.** Sessions have a max duration (default 2 hours, configurable from 30 minutes to 24 hours in Settings). The ADE extends it automatically while the agent is working or you're active, and warns you before an idle session expires.
* **Archive to clean up.** Archiving a chat (`Mod+Backspace`) terminates its sandbox but keeps the transcript, so you can still read (and unarchive) the conversation later.
* **Snapshot to keep VM state.** Take a snapshot of the sandbox (`Mod+Shift+S`) and start future chats from it. This is handy for preserving a fully warmed-up environment before archiving.

## Keyboard shortcuts

Press `Mod+/` in the app for the full list (`Mod` is `Cmd` on macOS, `Ctrl` on Linux). Highlights:

| Shortcut        | Action                  |
| --------------- | ----------------------- |
| `Mod+K`         | Command palette         |
| `Mod+E`         | Open review diff        |
| `Mod+J`         | Toggle terminal         |
| `Mod+G`         | Open files panel        |
| `Mod+D`         | Split pane side-by-side |
| `Mod+Shift+I`   | Change model            |
| `Mod+Shift+M`   | Change permission mode  |
| `Mod+Shift+S`   | Snapshot the sandbox    |
| `Mod+Shift+G`   | Open pull request       |
| `Mod+Backspace` | Archive chat            |

## Settings

**Settings** (`Mod+,`) covers, among other things:

* **General**: theme (system, light, dark, black), terminal and code fonts, the model used for drafting commit messages and PR text, smart chat titles, default sandbox size and session duration, and the update channel (stable or beta).
* **Providers**: agent sign-ins and API keys for Claude Code, Codex, and Pi; enable or disable individual providers.
* **Repositories**: manage your projects and their environments, and set the default environment for new chats.
* **Notifications**: the global toggle plus per-event settings.

> **Free to start:** Every workspace includes free storage and monthly credits. See the docs pricing page for current rates.

## What's next

* New to Tenki Sandbox? Read the [Concepts](https://tenki.cloud/docs/sandbox/concepts.md) page for how sessions, volumes, and snapshots fit together.
* Prefer code? The [Quickstart](https://tenki.cloud/docs/sandbox/quickstart.md) covers the CLI and the TypeScript, Go, and Python SDKs.
* Hit a problem? Check [Troubleshooting](https://tenki.cloud/docs/sandbox/troubleshooting.md) or email [hello@tenki.cloud](mailto:hello@tenki.cloud).

# Base Image (https://tenki.cloud/docs/sandbox/base-image)

What every Tenki Sandbox session ships with out of the box, and how to add your own tools.

Every Tenki Sandbox session starts from the same prepared **base image**, so common
runtimes and tools are already present the moment a session reaches `READY`. The
essentials need no install-and-warm-up step. This page lists what ships by default and
how to add anything else.

The base is a **standard Ubuntu 24.04 LTS** Linux VM. You log in as the `tenki` user
(uid 1000) with passwordless `sudo`, so you can `apt install`, `pip install`, or
`npm install` anything not listed here.

> **Versions change over time:** The versions below reflect the current base image and are refreshed as tools release updates. To see exactly what a live session has, run the version command for the tool (for example python3 --version or node --version) inside the session.

## Language runtimes

| Runtime | Version | Notes                                          |
| ------- | ------- | ---------------------------------------------- |
| Python  | 3.12    | Ubuntu 24.04 system Python, with `pip`         |
| Node.js | 24.14.0 | Installed via `nvm`; `npm` included            |
| Bun     | 1.3.14  | Fast JavaScript/TypeScript runtime and bundler |

## Package managers & language tooling

| Tool                       | Version | Purpose                                   |
| -------------------------- | ------- | ----------------------------------------- |
| pip                        | latest  | Python package installer                  |
| uv                         | 0.11.28 | Fast Python installer and resolver        |
| npm                        | bundled | Node package manager (with Node.js)       |
| pnpm                       | 10.20.0 | Fast, disk-efficient Node package manager |
| TypeScript (`tsc`)         | 5.9.3   | TypeScript compiler                       |
| ts-node                    | 10.9.2  | Run TypeScript directly                   |
| typescript-language-server | 5.3.0   | TypeScript/JavaScript LSP                 |

## Coding agents

Tenki Sandbox bakes in the major terminal coding agents so you can drive them directly
inside a session:

| Agent        | Command    | Version |
| ------------ | ---------- | ------- |
| Claude Code  | `claude`   | 2.1.209 |
| OpenAI Codex | `codex`    | 0.144.4 |
| opencode     | `opencode` | 1.17.20 |

## Python data & ML libraries

Preinstalled into the system Python so data and analysis workloads run without a setup
step:

| Category  | Package                | Version   |
| --------- | ---------------------- | --------- |
| Data core | numpy                  | 2.4.1     |
| Data core | pandas                 | 2.3.3     |
| Data core | matplotlib             | 3.10.8    |
| Data core | scipy                  | 1.17.0    |
| Data core | seaborn                | 0.13.2    |
| Data core | pillow                 | 12.1.0    |
| Data core | requests               | 2.32.5    |
| Data core | beautifulsoup4         | 4.14.3    |
| ML        | scikit-learn           | 1.8.0     |
| ML        | opencv-python-headless | 4.13.0.90 |

Heavier deep-learning frameworks (PyTorch, TensorFlow, Transformers, and similar) are
**not** preinstalled. They tend to be large and GPU-oriented, so it's best to pin them
per workload. Install them per session or bake them into a [template](https://tenki.cloud/docs/sandbox/templates.md).

## Common CLI tools

Available on `PATH` in every session:

* **Version control & GitHub:** `git`, `gh`
* **HTTP & transfer:** `curl`, `wget`, `rsync`
* **Search & data:** `ripgrep` (`rg`), `jq`, `sqlite3`
* **Archives:** `tar`, `zip`/`unzip`, `zstd`, `bzip2`, `xz`
* **Build:** `build-essential` (gcc/make), `pkg-config`
* **SSH:** `openssh-client`, `openssh-server`
* **Inspect:** `file`, `less`, `lsof`

## Checking what's installed

Because you have `sudo`, you can inspect anything from inside a session:

```bash
python3 --version
node --version
claude --version
python3 -c "import numpy, pandas, sklearn; print(numpy.__version__, pandas.__version__)"
dpkg -l | grep -i ripgrep
```

## Adding your own tools

For a one-off session, just install what you need:

```bash
pip install polars
sudo apt-get update && sudo apt-get install -y ffmpeg
npm install -g some-cli
```

If every session should start with the same extra tools, define them once in a
[template](https://tenki.cloud/docs/sandbox/templates.md) instead of installing on each session — the template
build captures the prepared environment as a snapshot so new sessions start ready.

> **Need a package added to the base?:** If you think a tool or library is broadly useful enough to belong in the default base image, let us know. We keep the base intentionally lean, but the included package set evolves based on what customers reach for most.

# CLI Reference (https://tenki.cloud/docs/sandbox/cli)

Command reference for the `tenki` CLI covering authentication, session lifecycle, command execution, file transfer, port exposure, SSH, persistent volumes, and snapshots.

The `tenki` CLI drives sandboxes from the terminal. Every sandbox command lives under `tenki sandbox`, with `tenki sbx` available as a shorter alias.

Most session commands take a `--session <session-id>` flag. Set a current session once with `tenki sandbox set <session-id>` and you can omit `--session` on the commands that follow.

This page documents the commands used across the Sandbox docs. For the authoritative, always-current flag list, run `tenki sandbox --help` (or `--help` on any subcommand).

## Authentication

```bash
# Interactive browser sign-in and workspace choice
tenki login

# Headless: print the sign-in URL instead of opening a browser
tenki login --no-browser

# Sign in with an API key (no browser), recommended for CI
tenki login --api-key tk_your_api_key

# Confirm you are signed in
tenki status

# Print the CLI version
tenki --version
```

Browser sign-in creates a 30-day API key bound to the workspace you choose and stores it in the CLI. Every
Sandbox command infers its workspace from that credential; the CLI does not need a separate workspace selection.

The CLI and all SDKs also read credentials from the environment:

* `TENKI_API_KEY`: API key (tokens starting with `tk_` are sent as `Authorization: Bearer <token>`)
* `TENKI_API_URL`: override the API endpoint (defaults to `https://api.tenki.cloud`)

## Sessions

### create

Create a session and, by default, wait for it to reach `RUNNING` before printing the session ID.

```bash
tenki sandbox create --name demo --cpu 2 --memory-mb 4096
```

* `--name <name>`: human-readable session name
* `--cpu <cores>`: vCPU cores
* `--memory-mb <mb>`: memory in MB
* `--disk-size-gb <gb>`: root disk size in GB
* `--allow-inbound`: enable inbound exposure (preview URLs)
* `--allow-outbound`: allow the guest to make outbound network calls
* `--metadata <key>=<value>`: attach metadata (repeatable)
* `--env <key>=<value>`: set a guest environment variable (repeatable)
* `--tags <tag>`: freeform tags for filtering (repeatable, or comma-separated; not `key=value`)
* `--authorized-key <key>` / `--authorized-keys-file <path>`: SSH public keys to install in the guest
* `--volume <volume-id>:<mount-path>[:ro]`: attach a persistent volume at a mount path (append `:ro` for read-only)
* `--snapshot <snapshot-id>`: start from a snapshot instead of a fresh image
* `--image <ref>`: start from a published registry image, `<workspace>/<artifact>[:tag]` (mutually exclusive with `--snapshot`)
* `--max-duration <duration>`: hard cap on the session's lifetime
* `--idle-timeout <duration>`: terminate the session after it sits idle this long
* `--pause-retention <duration>`: how long a paused session's state is retained
* `--sticky`: keep the session alive until it is explicitly terminated
* `--no-wait`: return immediately instead of waiting for `RUNNING`
* `--wait-timeout <duration>`: how long to wait for `RUNNING` before giving up

```bash
# From a snapshot, with a cache volume mounted
tenki sandbox create --snapshot <snapshot-id> --volume <volume-id>:/workspace/cache

# With metadata
tenki sandbox create --metadata owner=alice --metadata job=ci-1234
```

### set

Persist a session as the current one so later commands can omit `--session`.

```bash
tenki sandbox set <session-id>
```

### list

List sessions. Add `--json` for machine-readable output.

```bash
tenki sandbox list
tenki sandbox list --json
```

### get

Inspect a single session.

```bash
tenki sandbox get --session <session-id>
tenki sandbox get --session <session-id> --json
```

### exec

Run a command inside a session.

```bash
# Through a shell (pipes, redirects, globs, $VAR, && and & all work)
tenki sandbox exec --session <session-id> -c 'npm ci && npm test'

# Run a program directly, with no shell
tenki sandbox exec --session <session-id> -- go test ./...
```

* `-c, --shell <line>`: run the line through a shell
* `--`: pass the remaining arguments to the program directly (no shell)
* `--timeout <duration>`: command timeout (e.g. `2m`, `5m`)

Streamed stdout and stderr print live, followed by the final status, exit code, and duration.

### write / read

Move files in and out of the session. Paths are rooted in the working directory `/home/tenki`; `/workspace/...` paths exist only where a volume is mounted.

```bash
# Write from inline data, a local file, or stdin
tenki sandbox write --session <session-id> --path /home/tenki/app.env --data 'PORT=3000'
tenki sandbox write --session <session-id> --path /home/tenki/config.json --data-file ./config.json
echo 'hello sandbox' | tenki sandbox write --path hello.txt

# Read to stdout, or save to a local file with --out
tenki sandbox read --session <session-id> --path /home/tenki/config.json
tenki sandbox read --session <session-id> --path /home/tenki/build.log --out ./build.log
```

### expose / unexpose / ports

Expose a guest port through a preview URL, list exposed ports, and remove an exposure.

```bash
tenki sandbox expose --session <session-id> --port 3000
tenki sandbox ports --session <session-id>
tenki sandbox unexpose --session <session-id> --port 3000
```

### ssh

Open an SSH session, forward a port, or manage local SSH config and authorized keys.

```bash
# Open a shell
tenki sandbox ssh --session <session-id>

# Forward a local port to the guest
tenki sandbox ssh <session-id> -L 8080:127.0.0.1:8080

# Managed SSH config
tenki sandbox ssh config install
tenki sandbox ssh config status
tenki sandbox ssh config uninstall

# Set the guest's authorized keys
tenki sandbox ssh-keys set --session <session-id> --keys-file ~/.ssh/authorized_keys
```

### pause / resume

Pause a session to free compute while preserving its files and memory, then resume it later.

```bash
tenki sandbox pause --session <session-id>
tenki sandbox resume --session <session-id>
```

### terminate

Tear a session down.

```bash
tenki sandbox terminate --session <session-id>
```

## Volumes

Persistent volumes belong to the API key's workspace and survive session termination.

```bash
# Create
tenki sandbox volume create --name npm-cache --size 20GB

# List, inspect, resize, delete
tenki sandbox volume list
tenki sandbox volume list --json
tenki sandbox volume get <volume-id>
tenki sandbox volume resize <volume-id> --size 40GB
tenki sandbox volume delete <volume-id>

# Attach to / detach from a running session
tenki sandbox volume attach <session-id> <volume-id> --mount /workspace/cache
tenki sandbox volume attach <session-id> <volume-id> --mount /workspace/reference --readonly
tenki sandbox volume detach <session-id> <volume-id>
```

* `--name <name>`: volume name
* `--size <size>`: size, accepts units (`20GB`, `10GiB`) or a plain MiB number (`1024`)
* `--mount <path>`: mount path when attaching
* `--readonly`: mount read-only

To attach a volume at create time instead, use `tenki sandbox create --volume <volume-id>:<mount-path>[:ro]`.

## Snapshots

Capture a point-in-time VM snapshot, then restore it later as a new session.

```bash
# Create from a running session (waits for READY by default)
tenki sandbox snapshot create --session <session-id> --name baseline
tenki sandbox snapshot create --session <session-id> --name with-strace --wait-timeout 10m

# List, inspect, delete
tenki sandbox snapshot list
tenki sandbox snapshot list --json
tenki sandbox snapshot get <snapshot-id>
tenki sandbox snapshot delete <snapshot-id>

# Restore as a new session
tenki sandbox snapshot restore <snapshot-id> --name restored-copy
```

* `--session <session-id>`: source session for `create`
* `--name <name>`: name for the snapshot or the restored session
* `--wait-timeout <duration>`: how long `create` waits for the snapshot to become `READY`

Snapshots capture VM state, not attached volumes, so reattach volumes explicitly when you restore. You can also create a session from a snapshot with `tenki sandbox create --snapshot <snapshot-id>`.

## Templates

A template is a reusable definition of a prepared environment. Build it once, publish it to the registry, then create sessions from the published reference. See [Templates](https://tenki.cloud/docs/sandbox/templates.md) for the full workflow.

```bash
# Define a template (only --name and --setup-script are required)
tenki sandbox template create \
  --name my-node-env \
  --setup-script 'curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs' \
  --start-cmd 'node --version' \
  --env NODE_ENV=production

# Build it and wait for READY
tenki sandbox template build <template-id> --wait

# List, inspect, update, delete
tenki sandbox template list
tenki sandbox template get <template-id>
tenki sandbox template update <template-id> --start-cmd 'node server.js'
tenki sandbox template delete <template-id>
```

* `--name <name>`: template name (required for `create`)
* `--setup-script <script>`: shell script run at build time (required for `create`)
* `--start-cmd <cmd>`: command run when a session from the template starts
* `--env <key>=<value>`: environment variable (repeatable)
* `--cpu <cores>` / `--memory-mb <mb>` / `--disk-size-gb <gb>`: default resources for sessions built from the template
* `--tags <tag>`: freeform tags for filtering (repeatable)

Templates belong to the workspace bound to the API key.

`template build` takes `--wait` (block until `READY`, default 15m), `--wait-durable` (also wait for the snapshot upload), and `--wait-timeout <duration>`.

## Registry

The registry is a per-workspace namespace of publishable artifacts (templates or snapshots). Publishing gives an artifact a reference, `<workspace>/<artifact>[:tag]`, that `create --image` accepts.

```bash
# Publish a template (or a snapshot) as a named, versioned artifact
tenki sandbox registry publish \
  --image myworkspace/my-node-env:latest \
  --from-template <template-id> \
  --visibility private

# Browse and resolve artifacts
tenki sandbox registry list
tenki sandbox registry list --kind template
tenki sandbox registry get <workspace>/<artifact>
tenki sandbox registry resolve <workspace>/<artifact>:latest

# Create a session from a published reference
tenki sandbox create --image myworkspace/my-node-env:latest

# Release an eligible historical version's snapshot pin
tenki sandbox registry version delete myworkspace/my-node-env --snapshot-id <snapshot-id>
tenki sandbox registry version delete myworkspace/my-node-env --snapshot-id <snapshot-id> --json
```

* `--image <ref>`: the artifact reference to publish, `<workspace>/<artifact>[:tag]` (required)
* `--from-template <id>` / `--from-snapshot <id>`: the source to publish (exactly one)
* `--visibility <private|public|shared>`: who can pull the artifact (default `private`)
* `--label <label>` / `--title <title>` / `--description <text>`: optional metadata

Grant cross-workspace access with `tenki sandbox registry share --target-workspace <workspace-id>`; remove it with `unshare` or `share-revoke-grant`.

`registry version delete` removes one historical registry version, not the underlying snapshot. The version must be untagged, not the latest version of the image, and unused by a share. If one of those conditions fails, publish a newer version, move the tag, or revoke the share first. Once the command succeeds, delete the released snapshot separately with `tenki sandbox snapshot delete <snapshot-id>`.

Use `--json` or `--output yaml` for structured output; both include `image_id` and `snapshot_id`. When a delete is blocked, the error message names the rule that stopped it, such as `latest registry image version cannot be deleted` or `tagged registry image version cannot be deleted`.

# Concepts (https://tenki.cloud/docs/sandbox/concepts)

Understand the primitives behind Tenki Sandbox, including sessions, persistent volumes, snapshots, and templates, and when to reach for each.

Tenki Sandbox is built around a few primitives. Most workflows combine two or three of them.

| Primitive | What it is                                                          | Lifetime                        |
| --------- | ------------------------------------------------------------------- | ------------------------------- |
| Session   | A running full Linux VM                                             | Until you pause or terminate it |
| Volume    | Workspace-scoped persistent block storage                           | Across sessions                 |
| Snapshot  | A point-in-time capture of one session's VM state (disk and memory) | Until deleted or expired        |
| Template  | A named, reusable definition of a prepared environment              | Until deleted                   |
| Image     | The session source a template build produces, addressed by a digest | Until deleted from the registry |

## Sessions

A session is an isolated Linux VM, and the main thing you drive in Tenki Sandbox. You control its CPU and memory, network access, and environment, and can attach volumes and SSH keys. Every session starts from the same [base image](https://tenki.cloud/docs/sandbox/base-image.md), with common runtimes and tools already installed.

### Lifecycle

You create a session, it enters a running state, and from there you can:

* **Snapshot it** to capture its state and start new sessions from it later. The session briefly pauses, then keeps running.
* **Pause it** to free compute while preserving files and memory, then resume later. A paused session stops accruing metered charges, and its preserved state counts against your workspace storage quota.
* **Terminate it** to release all resources. A terminated session cannot be resumed.

The public lifecycle states are `CREATING`, `RUNNING`, `PAUSED`, `TERMINATING`, and `TERMINATED`. A session is ready to use once it reaches `RUNNING`; `TERMINATED` is final.

See [Sessions](https://tenki.cloud/docs/sandbox/sessions.md) for exec, files, ports, and SSH, and the [SDK reference](https://tenki.cloud/docs/sandbox/sdk.md) for resource limits.

## Persistent volumes

A volume is workspace-scoped block storage that you attach to a session and keep after the session ends. Reach for one when data needs to outlive a single VM:

* package and build caches
* large repositories
* datasets shared across sessions

A volume lives separately from the VM root disk, and it is never attached automatically; you attach it explicitly, at create time or later.

See [Volumes](https://tenki.cloud/docs/sandbox/volumes.md) for the full API.

## Snapshots

A snapshot captures both a session's disk and memory, so a restored session comes back with its running processes and in-memory state intact, not just its files.

A snapshot is one-to-many: you can start many new sessions from the same snapshot. Reach for one when:

* you want to preserve the exact state of a session
* you want a fast restore point
* you want to fork a running environment

Snapshot states: `CREATING`, `READY`, `FAILED`, `DELETING`, `DELETED`.

### Snapshot vs pause/resume

Both hold on to a session's state, but they solve different problems:

|                      | Pause / resume                                | Snapshot                                   |
| -------------------- | --------------------------------------------- | ------------------------------------------ |
| The original session | Pauses (stops) the session                    | Session briefly pauses, then keeps running |
| How many you get     | One-to-one: resume restores the same session  | One-to-many: one snapshot starts many      |
| When to use it       | Set a session aside and pick it back up later | Create a reusable checkpoint               |

See [Snapshots](https://tenki.cloud/docs/sandbox/snapshots.md) for the workflow.

## Templates

A template is a typed recipe for a prepared environment, so every session can start from the same known state. You declare a base image, a Git context to fetch, ordered build steps, runtime behavior, and default resources. Tenki builds the template by fetching the context, running the steps, and capturing the result.

A successful build automatically registers a private image, addressed by a content digest, and you create sessions from its reference, like `myworkspace/my-node-env`. Publishing to change an image's visibility or share it across workspaces is a separate, optional step. Every session you create from the image starts from that prepared state, so you skip the install-and-warm-up step each time. See [Templates](https://tenki.cloud/docs/sandbox/templates.md) for the full workflow.

### Snapshots vs templates

Both give you a reusable starting point, but they are not the same:

|                  | Template                                 | Snapshot                                      |
| ---------------- | ---------------------------------------- | --------------------------------------------- |
| How it's created | Declared before any session exists       | Captured from a running session               |
| What you get     | Produces the same environment every time | Captures whatever state existed at the moment |
| When to use it   | Repeatable environments                  | Checkpointing, rollback, forking              |

A snapshot is a low-level captured state; a template is the reusable recipe. Building a template runs your configuration and registers the result as a private image (backed by a snapshot), so every session from that image starts from the same place. Use templates when every session should start from an identical, known environment; use snapshots when you need to capture or fork live state that depends on what happened during a run.

## Choosing the right primitive

| You want…                                                      | Reach for… |
| -------------------------------------------------------------- | ---------- |
| An ephemeral VM for a single task                              | Session    |
| Data that outlives the VM                                      | Volume     |
| An exact restore of one VM's state                             | Snapshot   |
| Every session to start from an identical, prepared environment | Template   |

# Quickstart (https://tenki.cloud/docs/sandbox/quickstart)

Spin up your first Tenki Sandbox session in under a minute. Install the CLI or SDK, authenticate with an API key, and run commands inside an isolated Linux VM.

Tenki Sandbox gives you disposable full Linux VMs you can drive from the CLI or the Go, TypeScript, and Python SDKs. This guide takes you from install to a running sandbox in a few minutes. Pick your tool in the first code block and the selection follows you down the page.

## 1. Install

**CLI**
```bash
curl -fsSL https://tenki.cloud/install.sh | bash
```

Pin a version with `bash -s -- --version <x>` or change the location with `TENKI_INSTALL_DIR`. See the [CLI Reference](https://tenki.cloud/docs/sandbox/cli.md) for more.

**TypeScript**
```bash
npm install @tenkicloud/sandbox
```

**Go**
```bash
go get github.com/LuxorLabs/tenki-sdk-go/sandbox
```

**Python**
Requires Python 3.10+.

```bash
pip install tenki
```

## 2. Authenticate

Sign the CLI in interactively. For SDKs and automation, Sandbox onboarding creates an initial API key. Export it
as `TENKI_API_KEY`. See [Manage API keys](https://tenki.cloud/docs/account/api-keys.md) to create additional keys, choose an
expiration date, rotate keys, or revoke them.

**CLI**
```bash
# Opens your browser to sign in and choose a workspace
tenki login

# Confirm you are signed in
tenki status
```

Browser sign-in creates a 30-day API key bound to the workspace you choose and stores it in the CLI. Sandbox
commands infer their workspace from that credential.

Prefer an existing key? Run `tenki login --api-key tk_your_api_key`. See
[Authentication](https://tenki.cloud/docs/sandbox/cli.md#authentication) for headless and CI options.

**TypeScript**
```bash
export TENKI_API_KEY=tk_your_api_key
```

**Go**
```bash
export TENKI_API_KEY=tk_your_api_key
```

**Python**
```bash
export TENKI_API_KEY=tk_your_api_key
```

## 3. Create a sandbox and run a command

Create a session, run a command inside it, and read the output back. The session is a fresh Linux VM, isolated from your machine.

**CLI**
```bash
# Create a session (waits for RUNNING and prints the session ID)
tenki sandbox create --name demo

# Make it your current session so later commands can omit --session
tenki sandbox set <session-id>

# Run a command inside it
tenki sandbox exec -c 'uname -a && whoami'

# Tear it down
tenki sandbox terminate
```

**TypeScript**
```typescript
// sandbox.ts
import { stdoutText, TenkiSandbox } from "@tenkicloud/sandbox";

const sandbox = new TenkiSandbox(); // reads TENKI_API_KEY from env

await using session = await sandbox.createAndWait({ name: "demo" });

const result = await session.exec("bash", { args: ["-lc", "uname -a && whoami"] });
console.log(`exit=${result.exitCode}\n${stdoutText(result)}`);
// `await using` closes the session when it leaves scope.
```

Run it:

```bash
npx tsx sandbox.ts
```

**Go**
```go
// main.go
package main

import (
  "context"
  "log"
  "time"

  tenkisandbox "github.com/LuxorLabs/tenki-sdk-go/sandbox"
)

func main() {
  ctx := context.Background()

  client, err := tenkisandbox.New() // reads TENKI_API_KEY from env
  if err != nil {
    log.Fatal(err)
  }
  defer client.Close()

  session, err := client.CreateAndWait(ctx, 3*time.Minute, tenkisandbox.WithName("demo"))
  if err != nil {
    log.Fatal(err)
  }
  defer session.Close(ctx) // tears the session down on return

  result, err := session.Exec(ctx, "bash", tenkisandbox.WithArgs("-lc", "uname -a && whoami"))
  if err != nil {
    log.Fatal(err)
  }
  log.Printf("exit=%d\n%s", result.ExitCode, result.StdoutString())
}
```

Run it:

```bash
go run main.go
```

**Python**
```python
# sandbox.py
from tenki import Sandbox

# Reads TENKI_API_KEY from env. Waits for RUNNING; closes on block exit.
with Sandbox.create(name="demo") as sb:
    result = sb.exec("bash", "-lc", "uname -a && whoami")
    print(f"exit={result.exit_code}\n{result.stdout_text}")
```

Run it:

```bash
python sandbox.py
```

You should see the guest's kernel info and username printed back. That output came from inside the VM.

## What's next

* Do more with a session: [Sessions](https://tenki.cloud/docs/sandbox/sessions.md) covers command execution, file I/O, port exposure, and SSH.
* [Concepts](https://tenki.cloud/docs/sandbox/concepts.md): how sessions, volumes, and snapshots fit together.
* [Recipes](https://tenki.cloud/docs/sandbox/recipes.md): run an AI agent, checkpoint an environment, cache dependencies.
* [Persistent Volumes](https://tenki.cloud/docs/sandbox/volumes.md) and [Snapshots](https://tenki.cloud/docs/sandbox/snapshots.md) for durable state.
* [CLI Reference](https://tenki.cloud/docs/sandbox/cli.md) and [SDK Reference](https://tenki.cloud/docs/sandbox/sdk.md) for every command and option.
* Prefer a desktop app? The [Sandbox ADE](https://tenki.cloud/docs/sandbox/ade.md) runs coding agents like Claude Code and Codex in sandbox sessions.

Need help? Email [hello@tenki.cloud](mailto:hello@tenki.cloud) and we'll help you get set up.

# Recipes (https://tenki.cloud/docs/sandbox/recipes)

Task-oriented recipes for common Tenki Sandbox workflows, including running AI agents, checkpointing environments, caching dependencies, and executing untrusted code.

Short, end-to-end workflows built from the sandbox primitives. Each recipe assumes you have authenticated (see the [Quickstart](https://tenki.cloud/docs/sandbox/quickstart.md)) and links to the reference for the APIs it uses.

## Run an AI agent against a repository

Give an agent a disposable, isolated place to work. Clone a repo into a fresh session and run your agent inside it, so it can run commands and edit files without touching your machine.

```python
from tenki import Sandbox

# The `with` block tears the session down on exit.
with Sandbox.create(name="agent-run", cpu_cores=2, memory_mb=4096) as sb:
    sb.git.clone("https://github.com/org/repo", depth=1, directory="/home/tenki/repo")

    # Run the coding agent of your choice inside the VM. Everything it does
    # stays in the sandbox.
    result = sb.exec("bash", "-lc", "cd /home/tenki/repo && my-agent run --task 'fix the failing tests'")
    print(result.stdout_text)
```

To act on a pull request instead of a branch, swap the clone for `sb.git.fetch_pr(<number>, directory="/home/tenki/repo")`. To run [OpenCode](https://opencode.ai) in the session, pass `enable_opencode=True` at create time. See the [SDK Reference](https://tenki.cloud/docs/sandbox/sdk.md) for Git helpers.

## Checkpoint a prepared environment

Set up an environment once, snapshot it, and restore that exact state whenever you need it, instead of reinstalling every time.

```bash
# Prepare a session
tenki sandbox create --name baseline-build
tenki sandbox exec -c 'apt-get update && apt-get install -y strace && npm ci'

# Capture the prepared state
tenki sandbox snapshot create --session <session-id> --name baseline

# Later, restore it as a new session (no reinstall)
tenki sandbox create --snapshot <snapshot-id>
```

Snapshots capture VM state, not attached volumes, so reattach any volumes explicitly on the restored session. See [Snapshots](https://tenki.cloud/docs/sandbox/snapshots.md).

## Cache dependencies across sessions

Put a package cache on a persistent volume so dependency installs stay warm between sessions.

```bash
# Create a workspace-scoped volume once
tenki sandbox volume create --name pnpm-cache --size 20GB

# Mount it into a session at create time
tenki sandbox create --name dev --volume <volume-id>:/workspace/.pnpm-store
tenki sandbox exec --session <session-id> -c 'pnpm install'

# A later session reuses the warm cache
tenki sandbox create --name dev-2 --volume <volume-id>:/workspace/.pnpm-store
```

The volume survives session termination, so the second `pnpm install` reuses what the first one downloaded. See [Persistent Volumes](https://tenki.cloud/docs/sandbox/volumes.md).

## Share a read-only dataset

Load a dataset onto a volume once, then mount it read-only into many sessions at the same time, with no per-session copy.

```bash
# Create a volume and load your dataset into it
tenki sandbox volume create --name fixtures --size 10GB

# Mount it read-only (the :ro suffix) into any session
tenki sandbox create --volume <volume-id>:/mnt/fixtures:ro
```

The same volume can back many concurrent sessions read-only. See [Persistent Volumes](https://tenki.cloud/docs/sandbox/volumes.md).

## Run untrusted code and collect output

Execute code you don't trust in a disposable session, capture its result, and tear it down.

```bash
tenki sandbox create --name scratch --cpu 2 --memory-mb 4096
tenki sandbox exec --session <session-id> --timeout 2m -c './untrusted-script.sh'
tenki sandbox read --session <session-id> --path /home/tenki/build.log --out ./build.log
tenki sandbox terminate --session <session-id>
```

`exec` streams stdout and stderr and reports the exit code and duration, so you can gate on the result. Nothing runs on your host; the session is a fresh Linux VM that you throw away. See [Sessions](https://tenki.cloud/docs/sandbox/sessions.md).

# SDK Reference (https://tenki.cloud/docs/sandbox/sdk)

Programmatic reference for Tenki Sandbox covering installation, authentication, client options, identity discovery, OpenCode integration, and error types.

Tenki Sandbox has official SDKs for Go, TypeScript, and Python. All three wrap the same public service contract (`tenki.sandbox.v1`), so you get equivalent functionality whichever language you choose.

## Install

**TypeScript**
```bash
npm install @tenkicloud/sandbox
```

**Python**
Requires Python 3.10+.

```bash
pip install tenki
```

**Go**
```bash
go get github.com/LuxorLabs/tenki-sdk-go/sandbox
```

## Authenticate

The public SDKs authenticate with Workspace API keys (`tk_...`), sent as `Authorization: Bearer <token>`. Each key
is bound to one workspace, and Sandbox requests infer that workspace automatically.

### Resolution order

Every SDK resolves the auth token the same way: the token you pass explicitly (`WithAuthToken()` in Go, `authToken` in TypeScript, `auth_token=` in Python), then `TENKI_AUTH_TOKEN`, then `TENKI_API_KEY`.

The base URL resolves the same way: the explicit option (`WithBaseURL()` / `baseUrl` / `base_url=`), then `TENKI_API_ENDPOINT`, then the legacy `TENKI_API_URL`, then `https://api.tenki.cloud`.

## Create a client

**TypeScript**
```typescript
import { TenkiSandbox } from "@tenkicloud/sandbox";

const sandbox = new TenkiSandbox(); // env-driven

// Or explicit:
const sandbox = new TenkiSandbox({
  authToken: "tk_...",
  baseUrl: "https://api.tenki.cloud",
});
```

**Python**
The Python SDK exposes a low-level `Client` for resource APIs (volumes, snapshots) and a high-level `Sandbox` for driving a single session.

```python
from tenki import Client, Sandbox

# Resource client, env-driven (reads TENKI_API_KEY and TENKI_API_ENDPOINT).
client = Client()

# Or explicit:
client = Client(
    auth_token="tk_your_api_key",
    base_url="https://api.tenki.cloud",
)

# Create and drive a session directly. `Sandbox.create` waits for RUNNING by
# default and doubles as a context manager that terminates on exit.
with Sandbox.create(name="demo", cpu_cores=2, memory_mb=4096) as sb:
    result = sb.exec("python3", "-c", "print('hello')")
    print(result.stdout_text)
```

`Sandbox.create` also accepts the client options (`auth_token`, `base_url`, `timeout`), since it constructs the client for you.

**Go**
```go
import tenkisandbox "github.com/LuxorLabs/tenki-sdk-go/sandbox"

// Zero-config: reads TENKI_API_KEY and TENKI_API_URL.
client, err := tenkisandbox.New()

// Explicit:
client, err := tenkisandbox.New(
  tenkisandbox.WithAuthToken("tk_your_api_key"),
  tenkisandbox.WithBaseURL("https://api.example.com"),
)
defer client.Close()
```

Useful client options:

| Option                          | Description                       | Default                   |
| ------------------------------- | --------------------------------- | ------------------------- |
| `WithAuthToken(token)`          | API authentication token          | `TENKI_API_KEY` env       |
| `WithBaseURL(url)`              | Sandbox service endpoint          | `https://api.tenki.cloud` |
| `WithHTTPTimeout(d)`            | HTTP timeout                      | `30s`                     |
| `WithHTTPClient(c)`             | Custom `*http.Client`             | auto-created              |
| `WithConnectClientOptions(...)` | Additional Connect client options | none                      |

To create and drive a session, every SDK and the CLI accept the same set of options. See [Create a session](https://tenki.cloud/docs/sandbox/sessions.md#create-a-session) for the full list.

## Defaults

Defaults applied by `Create` when you do not override them:

* `cpu`: `2`
* `memory`: `4096 MB`

Networking is off unless you set `allowInbound` / `allowOutbound`. The CLI enables both by default.

Validation: `cpu_cores` `1..16`, `memory_mb` `128..65536`, volume size `1 MiB` to `100 GiB`.

## Identity

Use `WhoAmI` to inspect the authenticated owner and its workspace. Normal resource calls do not need the
workspace ID; the API key already supplies that scope.

**TypeScript**
```typescript
const me = await sandbox.whoAmI();
console.log(`${me.ownerType}/${me.ownerId}`);
```

**Python**
```python
identity = client.who_am_i()
print(f"owner: {identity.owner_type}/{identity.owner_id}")
for ws in identity.workspaces:
    print(f"workspace: {ws.name} ({ws.id})")
```

**Go**
```go
identity, err := client.WhoAmI(ctx)
fmt.Printf("owner: %s/%s\n", identity.OwnerType, identity.OwnerID)
for _, ws := range identity.Workspaces {
  fmt.Printf("workspace: %s (%s)\n", ws.Name, ws.ID)
}
```

## OpenCode integration

Sessions can run [OpenCode](https://opencode.ai) inside the VM for AI-driven workflows. Enable it at create time with the `enableOpenCode` option (`WithOpenCode` in Go, `enable_opencode` in Python). In the TypeScript and Go SDKs you can also pass a provider option (`openCodeProvider` / `WithOpenCodeProvider`) to wire in your keys. See [Create a session](https://tenki.cloud/docs/sandbox/sessions.md#create-a-session) for those options.

OpenCode then runs inside the session. The SDKs enable it at create time but do not expose an API for driving it programmatically once the session is running.

## Git helpers

The SDK exposes structured Git operations on a session.

**TypeScript**
```typescript
await session.git.clone("https://github.com/org/repo", { depth: 1 });
await session.git.checkout("feature");
const diff = await session.git.diff({});
const log = await session.git.log({ maxCount: 10 });
await session.git.fetchPR(42, { remote: "origin" });
```

**Python**
```python
sb.git.clone("https://github.com/octocat/Hello-World.git", depth=1, directory="/home/tenki/repo")
sb.git.checkout("main")
diff = sb.git.diff()
log = sb.git.log(max_count=10)
sb.git.fetch_pr(123, directory="/home/tenki/repo")
```

**Go**
```go
out, err := session.Git.Clone(ctx, "https://github.com/octocat/Hello-World.git", tenkisandbox.GitCloneParams{
  Directory: "/home/tenki/repo",
  Depth:     1,
})
out, err = session.Git.Checkout(ctx, "main", tenkisandbox.GitCheckoutParams{})
out, err = session.Git.FetchPR(ctx, 123, tenkisandbox.GitFetchPRParams{
  Directory: "/home/tenki/repo",
})
```

You can also inject a GitHub token at session create time (`WithGitHubToken(token)` in Go, the `githubToken` option in TypeScript, or `github_token=` in Python) so private clones work without provisioning credentials inside the guest.

## Registry version pruning

Published registry versions pin their source snapshots. Delete an eligible historical version to release that pin; the version must be untagged, not the image's latest version, and unused by a share. The SDK methods take the registry image ID and snapshot ID, and return both IDs after deletion.

**TypeScript**
```typescript
const deleted = await sandbox.deleteRegistryImageVersion(imageId, snapshotId);
console.log(deleted.imageId, deleted.snapshotId);
```

**Python**
```python
deleted = client.registry.delete_version(image_id, snapshot_id)
print(deleted.image_id, deleted.snapshot_id)
```

**Go**
```go
deleted, err := client.DeleteRegistryImageVersion(ctx, imageID, snapshotID)
fmt.Println(deleted.ImageID, deleted.SnapshotID)
```

Deleting a latest, tagged, or shared version fails with a failed-precondition error, and the message names the rule that blocked it. Deleting the registry version does not delete the snapshot; call the snapshot deletion API separately after the pin is released.

## Constants

The default operation timeouts are the same across SDKs:

| Operation       | Default   |
| --------------- | --------- |
| Create          | 180s (3m) |
| Exec            | 30s       |
| Snapshot create | 300s (5m) |
| Restore         | 300s (5m) |
| Volume detach   | 120s (2m) |

Each SDK exports them as named constants: Go `DefaultSessionCreateTimeout` and friends, TypeScript `DEFAULT_SESSION_CREATE_TIMEOUT_MS` (milliseconds), and Python `DEFAULT_CREATE_TIMEOUT` (seconds, in `tenki_sandbox.constants`).

For volume sizes, the SDKs export byte-multiplier constants (`KB`, `MB`, `GB`, and the binary `KiB`, `MiB`, `GiB`, and so on):

**TypeScript**
```typescript
import { GiB } from "@tenkicloud/sandbox";

const tenGiB = 10 * GiB;
```

**Python**
```python
from tenki import GiB

ten_gib = 10 * GiB
```

**Go**
```go
tenGiB := 10 * tenkisandbox.GiB
```

## Errors

Every SDK surfaces service errors as typed values, sharing a common base (`SandboxError` in the TypeScript and Python SDKs). The common ones:

| Meaning                  | Go                         | TypeScript                   | Python                       |
| ------------------------ | -------------------------- | ---------------------------- | ---------------------------- |
| Session not found        | `ErrSessionNotFound`       | `SessionNotFoundError`       | `SessionNotFoundError`       |
| Session expired          | `ErrSessionExpired`        | `SessionExpiredError`        | n/a                          |
| Session terminated       | `ErrSessionTerminated`     | `SessionTerminatedError`     | `SessionTerminatedError`     |
| Invalid state            | `ErrInvalidState`          | `InvalidStateError`          | `InvalidStateError`          |
| Command timeout          | `ErrCommandTimeout`        | `CommandTimeoutError`        | `CommandTimeoutError`        |
| Unauthorized             | `ErrUnauthorized`          | `UnauthorizedError`          | `UnauthorizedError`          |
| Permission denied        | `ErrPermissionDenied`      | `PermissionDeniedError`      | `PermissionDeniedError`      |
| Quota exceeded           | `ErrQuotaExceeded`         | `QuotaExceededError`         | `QuotaExceededError`         |
| Port limit exceeded      | `ErrPortLimitExceeded`     | `PortLimitExceededError`     | `PortLimitExceededError`     |
| Inbound disabled         | `ErrInboundDisabled`       | `InboundDisabledError`       | `InboundDisabledError`       |
| Rate limited             | `ErrRateLimited`           | `RateLimitedError`           | `RateLimitedError`           |
| Volume not found         | `ErrVolumeNotFound`        | `VolumeNotFoundError`        | `VolumeNotFoundError`        |
| Volume in use            | `ErrVolumeInUse`           | `VolumeInUseError`           | `VolumeInUseError`           |
| Snapshot not found       | `ErrSnapshotNotFound`      | `SnapshotNotFoundError`      | `SnapshotNotFoundError`      |
| Snapshot failed          | `ErrSnapshotFailed`        | `SnapshotFailedError`        | n/a                          |
| Registry image not found | `ErrRegistryImageNotFound` | `RegistryImageNotFoundError` | `RegistryImageNotFoundError` |

The Go SDK also defines `ErrSSHUnavailable` and `ErrVolumeLimitExceeded`. Catch errors the idiomatic way in each tool:

**TypeScript**
```typescript
import { CommandTimeoutError } from "@tenkicloud/sandbox";

try {
  await session.exec("sleep", { args: ["999"], timeoutMs: 1000 });
} catch (err) {
  if (err instanceof CommandTimeoutError) {
    console.log("Command timed out");
  }
}
```

**Python**
```python
from tenki import CommandTimeoutError

try:
    sb.exec("sleep", "999", timeout=1)
except CommandTimeoutError:
    print("Command timed out")
```

`result.check()` raises `CommandFailedError` on a non-zero exit, and `RateLimitedError` carries `retryable = True`. Python also defines `CommandFailedError`, `VolumeSyncPendingError`, and `SnapshotNotDurableError`.

**Go**
```go
if errors.Is(err, tenkisandbox.ErrSnapshotFailed) {
  // inspect the snapshot record and recreate
}
```

## Advanced API surface

The public service contract also exposes lower-level RPCs that the convenience SDKs don't wrap:

* `PauseSession`, `ResumeSession`: present in the protobuf, not always wrapped, may not be available in every deployment

If you need them, integrate directly with the protocol:

* `proto/tenki/sandbox/v1/sandbox.proto`

> **Stick to the SDKs unless you need a raw RPC:** The Go, TypeScript, and Python SDKs are the officially supported surface for Tenki Sandbox. Only drop down to raw Connect/gRPC when an RPC isn't yet wrapped by an SDK, and keep in mind that a wrapper may be added in a future release.

# Sessions (https://tenki.cloud/docs/sandbox/sessions)

Create and drive Tenki Sandbox sessions covering lifecycle, command execution, file I/O, port exposure, and SSH access.

A session is a single running sandbox. This page covers the full session surface: lifecycle, command execution, file I/O, ports, and SSH. Pick your tool in any code block, and the selection syncs across the page.

## Create a session

**Python**
```python
from tenki import Sandbox

sb = Sandbox.create(
    name="demo",
    cpu_cores=4,
    memory_mb=8192,
    allow_inbound=True,
    allow_outbound=True,
    env={"APP_ENV": "dev"},
    metadata={"owner": "alice"},
)
```

`Sandbox.create` waits by default via a single server-held request and returns an exec-ready session with data-plane access primed. Pass `wait=False` to return immediately in `CREATING`. Use `Client().create(...)` instead when you want to manage the client lifecycle yourself.

**TypeScript**
```typescript
const session = await sandbox.create({
  name: "demo",
  cpuCores: 4,
  memoryMb: 8192,
  allowInbound: true,
  allowOutbound: true,
  env: { APP_ENV: "dev" },
  metadata: { owner: "alice" },
});
```

`create()` waits by default via a single server-held request and returns a run-ready session with data-plane access primed. Pass `waitReady: false` to return immediately in `CREATING`.

**Go**
```go
// Create waits by default and returns a RUNNING, exec-ready session.
session, err := client.Create(
  ctx,
  tenkisandbox.WithName("demo"),
  tenkisandbox.WithCPUCores(4),
  tenkisandbox.WithMemoryMB(8192),
  tenkisandbox.WithAllowInbound(true),
  tenkisandbox.WithAllowOutbound(true),
  tenkisandbox.WithEnvs(map[string]string{"APP_ENV": "dev"}),
  tenkisandbox.WithMetadata(map[string]string{"owner": "alice"}),
  tenkisandbox.WithWaitTimeout(3*time.Minute),
)

// Opt out when you want to orchestrate readiness separately.
session, err := client.Create(ctx, tenkisandbox.WithName("demo"), tenkisandbox.WithWaitReady(false))
// Later: session.WaitReady(ctx, 3*time.Minute)
```

**CLI**
```bash
tenki sandbox create \
  --name my-session \
  --cpu 4 \
  --memory-mb 8192 \
  --allow-inbound \
  --allow-outbound \
  --env APP_ENV=dev \
  --metadata owner=alice \
  --metadata purpose=review
```

By default, the CLI waits until the session is `RUNNING` and exec-ready before returning (a single server-held request). Pass `--no-wait` to return immediately.

Every create call takes the same options, named per tool:

| Option           | TypeScript                           | Python                            | Go                                      | CLI                                          |
| ---------------- | ------------------------------------ | --------------------------------- | --------------------------------------- | -------------------------------------------- |
| Name             | `name`                               | `name`                            | `WithName`                              | `--name`                                     |
| CPU / memory     | `cpuCores`, `memoryMb`               | `cpu_cores`, `memory_mb`          | `WithCPUCores`, `WithMemoryMB`          | `--cpu`, `--memory-mb`                       |
| Disk size        | `diskSizeGb`                         | `disk_size_gb`                    | `WithDiskSizeGB`                        | `--disk-size-gb`                             |
| Network          | `allowInbound`, `allowOutbound`      | `allow_inbound`, `allow_outbound` | `WithAllowInbound`, `WithAllowOutbound` | `--allow-inbound`, `--allow-outbound`        |
| Metadata / env   | `metadata`, `env`                    | `metadata`, `env`                 | `WithMetadata`, `WithEnvs`              | `--metadata`, `--env`                        |
| Tags             | `tags`                               | `tags`                            | `WithTags`                              | `--tags`                                     |
| SSH keys         | `sshAuthorizedKeys`                  | `ssh_authorized_keys`             | `WithSSHKeys`                           | `--authorized-key`, `--authorized-keys-file` |
| Volumes          | `volumes`                            | `volumes`                         | `WithVolume`                            | `--volume`                                   |
| Snapshot / image | `snapshotId`, `image`                | `snapshot_id`, `image`            | `WithSnapshot`, `WithImage`             | `--snapshot`, `--image`                      |
| Max duration     | `maxDurationMs`                      | `max_duration`                    | `WithMaxDuration`                       | `--max-duration`                             |
| Idle timeout     | `idleTimeoutMinutes`                 | `idle_timeout_minutes`            | `WithIdleTimeout`                       | `--idle-timeout`                             |
| Pause retention  | `pauseRetentionMs`                   | `pause_retention`                 | `WithPauseRetention`                    | `--pause-retention`                          |
| Sticky           | `sticky`                             | `sticky`                          | `WithSticky`                            | `--sticky`                                   |
| OpenCode         | `enableOpenCode`, `openCodeProvider` | `enable_opencode`                 | `WithOpenCode`, `WithOpenCodeProvider`  | n/a                                          |
| Clone repo       | `cloneRepoUrl`, `githubToken`        | `clone_repo_url`, `github_token`  | `WithCloneRepo`, `WithGitHubToken`      | n/a                                          |
| Wait for ready   | `waitReady`, `waitTimeoutMs`         | `wait`, `timeout`                 | `WithWaitReady`, `WithWaitTimeout`      | `--no-wait`, `--wait-timeout`                |

Unset options fall back to service defaults (2 vCPU, 4096 MB). The CLI enables inbound and outbound networking by default; with the SDKs, set `allowInbound` / `allowOutbound` to enable them.

## Manage a session

`WaitReady`/`wait_ready` is only needed for sessions obtained via get/list or created with wait disabled; the create calls above already return ready sessions.

**TypeScript**
```typescript
await session.refresh();
await session.extend(600_000); // +10 minutes
await session.pause();
await session.resume();
await session.close(); // or session.closeIfOpen(), or Symbol.asyncDispose

// List and inspect
const sessions = await sandbox.list();
const s = await sandbox.get(sessionId);
```

**Python**
```python
sb.wait_ready(180)
sb.refresh()
sb.extend(1800)  # +30 minutes (seconds or a timedelta)
sb.pause()
sb.resume()
sb.close()  # or sb.close_if_open(); the context manager closes on exit

# List and inspect
sessions = client.list()
sb = client.get(session_id)
```

**Go**
```go
err = session.WaitReady(ctx, 3*time.Minute)
err = session.Refresh(ctx)
err = session.Extend(ctx, 30*time.Minute)
err = session.Pause(ctx)
err = session.Resume(ctx)
err = session.Close(ctx)
err = session.CloseIfOpen(ctx)

// List and inspect
sessions, err := client.List(ctx)
session, err := client.Get(ctx, sessionID)
```

**CLI**
```bash
# List and inspect
tenki sandbox list
tenki sandbox list --json
tenki sandbox get --session <session-id>

# Pause, resume, terminate
tenki sandbox pause --session <session-id>
tenki sandbox resume --session <session-id>
tenki sandbox terminate --session <session-id>
```

## Command execution

**Python**
```python
# One-shot: collects stdout/stderr and returns a result
result = sb.exec("bash", "-lc", "echo $APP_ENV && make test", env={"APP_ENV": "ci"}, timeout=120)
if not result.ok:
    raise RuntimeError(f"failed: exit={result.exit_code} stderr={result.stderr_text}")

# Or start a live process and stream output
proc = sb.start("npm", "test")
proc.close_stdin()
for chunk in proc.stdout:
    print(chunk.decode(), end="")
proc.wait().check()
```

`exec` accepts `cwd`, `env`, `timeout`, `input`, and `check=True` (raises `CommandFailedError` on a non-zero exit). Use `sb.shell("...")` for shell parsing.

Result helpers: `result.stdout_text`, `result.stderr_text`, `result.ok`, `result.check()`.

**TypeScript**
```typescript
// One-shot
const result = await session.exec("npm", {
  args: ["test"],
  timeoutMs: 60_000,
  onOutput: (chunk) => process.stdout.write(chunk.data),
});

// Or stream explicitly
const stream = await session.stream("npm", { args: ["test"] });
for (;;) {
  const chunk = await stream.next();
  if (!chunk) break;
  process.stdout.write(chunk.data);
}
await stream.wait();
```

**Go**
```go
result, err := session.Exec(
  ctx,
  "bash",
  tenkisandbox.WithArgs("-lc", "echo $APP_ENV && make test"),
  tenkisandbox.WithEnv("APP_ENV", "ci"),
  tenkisandbox.WithTimeout(2*time.Minute),
)
if err != nil {
  log.Fatal(err)
}

if !result.Status.IsSuccess() {
  log.Fatalf("failed: exit=%d stderr=%s", result.ExitCode, result.StderrString())
}
```

Exec options: `WithArgs`, `WithTimeout`, `WithEnv`, `WithEnvs`.

Result helpers: `result.StdoutString()`, `result.StderrString()`, `result.Status.IsSuccess()`, `IsFailed()`, `IsTimedOut()`.

**CLI**
```bash
tenki sandbox exec --session <session-id> -c 'go test ./...'
tenki sandbox exec --session <session-id> --timeout 2m -c 'npm ci && npm test'
```

`-c` (short for `--shell`) runs the line through a shell so `&&`, pipes, redirects and globs work. Without it, `exec` runs the program directly with no shell; to pass flags straight to a program, put them after `--` (for example `tenki sandbox exec -- bash -lc '...'`).

CLI output includes:

* streamed stdout and stderr
* final status, exit code, and duration

## File operations

File operations are rooted in the session's working directory, `/home/tenki`. Relative paths resolve from there; absolute paths outside it (including `/tmp`) are rejected with a permission error.

**Python**
```python
sb.fs.write_text("/home/tenki/config.json", '{"key": "value"}')
data = sb.fs.read_text("/home/tenki/config.json")

# Bytes, directory listing, and local <-> guest transfers
sb.fs.write_bytes("/home/tenki/blob.bin", b"\x00\x01")
entries = sb.fs.list("/home/tenki")
sb.fs.upload("./local.tar", "/home/tenki/local.tar")
sb.fs.download("/home/tenki/build.log", "./build.log")
```

**TypeScript**
```typescript
await session.writeFile("/home/tenki/config.json", '{"key": "value"}');
const data = await session.readFile("/home/tenki/config.json");
```

**Go**
```go
err = session.WriteFile(ctx, "/home/tenki/hello.txt", []byte("hello"))
data, err := session.ReadFile(ctx, "/home/tenki/hello.txt")
```

**CLI**
```bash
# inline
tenki sandbox write --session <session-id> --path /home/tenki/app.env --data 'PORT=3000'

# from a local file
tenki sandbox write --session <session-id> --path /home/tenki/config.json --data-file ./config.json

# from stdin
cat ./local-file.txt | tenki sandbox write --session <session-id> --path /home/tenki/input.txt

# read to stdout
tenki sandbox read --session <session-id> --path /home/tenki/config.json

# read into a local file
tenki sandbox read --session <session-id> --path /home/tenki/build.log --out ./build.log
```

## Port exposure and networking

Each session has independent inbound and outbound settings:

* `allow_outbound=true` lets the guest make outbound network calls
* `allow_inbound=true` enables inbound exposure workflows

**Python**
```python
preview = sb.expose_port(3000, ttl=3600)  # ttl in seconds
print(preview.url)

ports = sb.list_exposed_ports()
sb.unexpose_port(3000)
```

**TypeScript**
```typescript
const port = await session.exposePort(3000, { ttlMs: 3600_000 });
console.log(port.previewUrl);
```

**Go**
```go
port, err := session.ExposePort(ctx, 3000)
ports, err := session.ListExposedPorts(ctx)
err = session.UnexposePort(ctx, 3000)
```

**CLI**
```bash
tenki sandbox expose --session <session-id> --port 3000
tenki sandbox ports --session <session-id>
tenki sandbox unexpose --session <session-id> --port 3000
```

When you expose a long-running server you started with `exec`, background it and detach its streams (`>/tmp/server.log 2>&1 </dev/null &`). `exec` streams the command's output until it closes, so a server that keeps the output stream open leaves `exec` waiting forever.

Use the `previewUrl` returned by each expose call rather than constructing hostnames yourself; the host pattern is not a stable contract.

## SSH access

Connect to a session over SSH. The CLI gives you an interactive shell, managed local config, and key management; the SDKs expose a raw byte-stream transport for wiring into your own SSH tooling. (Set keys at create time with the `sshAuthorizedKeys` option in the table above.)

**TypeScript**
Raw byte-stream transport for your own SSH tooling, plus replacing the authorized keys on a running session:

```typescript
const conn = await session.ssh();
await conn.write(new TextEncoder().encode("ls -la\n"));
const chunk = await conn.read(); // Uint8Array | null
if (chunk) process.stdout.write(chunk);
conn.close();

// Replace the authorized keys
await session.updateSshAuthorizedKeys(["ssh-ed25519 AAAA..."]);
```

**Python**
Raw byte-stream transport (an `io.RawIOBase`), plus replacing the authorized keys on a running session:

```python
conn = sb.ssh()
conn.write(b"ls -la\n")
print(conn.recv(4096).decode())
conn.close()

# Replace the authorized keys
sb.update_ssh_authorized_keys(["ssh-ed25519 AAAA..."])
```

**Go**
Raw byte-stream transport for your own SSH tooling, plus replacing the authorized keys on a running session:

```go
conn, err := session.SSH(ctx)
defer conn.Close()

// Replace the authorized keys
err = session.UpdateSSHAuthorizedKeys(ctx, []string{"ssh-ed25519 AAAA..."})
```

**CLI**
Open an interactive shell:

```bash
tenki sandbox ssh --session <session-id>
```

Useful flags: `--user` (default `tenki`), `--identity-file`, `--batch-mode`, `--connect-timeout`, `--strict-host-key-checking`. Pass standard SSH arguments after the session ID:

```bash
tenki sandbox ssh <session-id> -L 8080:127.0.0.1:8080
```

Install a managed entry in your local SSH config so you can use friendly aliases:

```bash
tenki sandbox ssh config install
tenki sandbox ssh config status
tenki sandbox ssh config uninstall
ssh sbx-<session-uuid>
```

Replace the authorized keys on a running session:

```bash
tenki sandbox ssh-keys set --session <session-id> --keys-file ~/.ssh/authorized_keys
```

## Session metadata

Metadata tags a session with arbitrary string key-value pairs (`metadata` in the SDKs, `--metadata key=value` on the CLI, both shown above). Use it to filter sessions in dashboards, attribute billing, or tie a session to an upstream job ID. Metadata is opaque to the service; it is for your bookkeeping.

# Snapshots (https://tenki.cloud/docs/sandbox/snapshots)

Capture a point-in-time VM snapshot of any Tenki Sandbox session, then restore it later as a new session.

A snapshot is a restorable VM capture of one session, including both disk and memory state. Restore a snapshot to spin up a new session in the exact state of the original.

## Manage snapshots

Pick your tool, and the selection syncs across the rest of the page.

### Create

**CLI**
```bash
tenki sandbox snapshot create --session <session-id> --name baseline
```

With expiration:

```bash
tenki sandbox snapshot create \
  --session <session-id> \
  --name before-upgrade \
  --expires-at 2026-03-20T12:00:00Z
```

**TypeScript**
```typescript
const snapshot = await sandbox.createSnapshotAndWait(session.id, {
  name: "after-setup",
});
```

**Go**
One-shot, returns once the snapshot is READY:

```go
snapshot, err := client.CreateSnapshotAndWait(
  ctx,
  session.ID,
  "baseline",
  nil,
  tenkisandbox.DefaultSnapshotCreateTimeout,
)
```

Or kick off the create async and wait separately:

```go
snapshot, err := client.CreateSnapshot(ctx, session.ID, "baseline", nil)
snapshot, err = client.WaitSnapshotReady(ctx, snapshot.ID, 5*time.Minute)
```

**Python**
```python
# From a live sandbox; waits for the snapshot to become READY by default.
snapshot = sb.snapshot(name="after-setup")
```

Or drive it through the client, optionally without waiting:

```python
snapshot = client.snapshots.create_and_wait(sb.id, name="baseline")

# Async, then wait separately:
snapshot = client.snapshots.create(sb.id, name="baseline")
snapshot = client.snapshots.wait_ready(snapshot.id, timeout=300)
```

### List, inspect, delete

**TypeScript**
```typescript
const snapshot = await sandbox.getSnapshot(snapshotId);
const snapshots = await sandbox.listSnapshots();
await sandbox.deleteSnapshot(snapshotId);
```

**Python**
```python
snapshot = client.snapshots.get(snapshot_id)
snapshots = client.snapshots.list()
snapshot = client.snapshots.delete(snapshot_id)
```

**Go**
```go
snapshot, err := client.GetSnapshot(ctx, snapshotID)
snapshots, err := client.ListSnapshots(ctx)
snapshot, err = client.DeleteSnapshot(ctx, snapshotID)
```

**CLI**
```bash
tenki sandbox snapshot list
tenki sandbox snapshot list --json
tenki sandbox snapshot get <snapshot-id>
tenki sandbox snapshot delete <snapshot-id>
```

## Published snapshots stay pinned

Publishing a snapshot creates a version of a registry image. Every registry version keeps its source snapshot pinned, so `snapshot delete` cannot remove that snapshot while any version still references it. Moving a tag does not remove the older version or release its pin.

To release an old snapshot:

1. Make the registry version eligible for deletion. It must not be the image's latest version, must be untagged, and must not be referenced by a share. Publish a newer version, move any tag to another version, and revoke any share that still uses it.

2. Delete the historical registry version by image ref or ID and snapshot ID:

   ```bash
   tenki sandbox registry version delete <image-ref-or-id> --snapshot-id <snapshot-id>
   ```

3. If no other references remain, delete the snapshot if you no longer need it:

   ```bash
   tenki sandbox snapshot delete <snapshot-id>
   ```

Deleting a registry version releases only that version's pin; it does not delete the snapshot itself. Other references can keep the snapshot pinned. In particular, a snapshot created by a template build can remain pinned by that build. A delete against a latest, tagged, or shared version fails, and the error names the rule that still applies.

### Restore

**CLI**
```bash
tenki sandbox snapshot restore <snapshot-id> --name restored-copy
```

`snapshot restore` is a convenience wrapper over:

```bash
tenki sandbox create --snapshot <snapshot-id>
```

**TypeScript**
```typescript
const restored = await sandbox.createAndWait({
  snapshotId: snapshot.id,
});
```

**Go**
```go
restored, err := client.Create(
  ctx,
  tenkisandbox.WithSnapshot(snapshotID),
  tenkisandbox.WithName("restored-copy"),
)
```

**Python**
```python
restored = Sandbox.create(snapshot_id=snapshot.id, name="restored-copy")
```

## Snapshot metadata

A snapshot moves through `CREATING`, `READY`, `FAILED`, `DELETING`, and `DELETED`; wait for `READY` before restoring from it. Each record also reports its size (`size_bytes`, `compressed_bytes`, `memory_bytes`), the session and base image it came from, when it was created, and an optional `expires_at` after which it is deleted.

## Volumes are not auto-restored

Snapshots capture disk and memory, but not a session's attached volumes. A restored session is a normal session, so it comes up with no volumes attached. Reattach any volume you need explicitly, at create time or with `volume attach`. See [Volumes](https://tenki.cloud/docs/sandbox/volumes.md) for the volume API.

## Errors

Snapshot calls can fail when the snapshot ID is unknown or when creation fails. Every SDK surfaces these as typed errors or exceptions; see the [SDK reference](https://tenki.cloud/docs/sandbox/sdk.md#errors) for the names in each language.

# Templates (https://tenki.cloud/docs/sandbox/templates)

Define a typed template from a Git context, build it into a private digest-addressed image, and create sessions from it.

A template is a reusable definition of a prepared environment. Instead of fetching a repo and installing the same tools at the start of every session, you define the environment once as a typed recipe, build it, and create sessions from the resulting image, so every session starts in the same known state. See [Concepts](https://tenki.cloud/docs/sandbox/concepts.md#templates) for how templates relate to snapshots and images.

Working with a template is three steps:

1. **Define** the spec: a base image, a Git context, ordered build steps, runtime behavior, and default resources.
2. **Build** it. Tenki fetches the context, runs the steps, and captures the result. A successful build automatically registers a private image, versioned and addressed by a real content digest.
3. **Create** sessions from that image.

Publishing is a separate, optional step: it changes an image's visibility or sharing. Builds never make an image public on their own.

## Primitives

A template is defined by a `TemplateSpec`, the recipe you build. It is one of a few related things worth keeping straight:

| Primitive       | What it is                                                                                  | Lifetime                          |
| --------------- | ------------------------------------------------------------------------------------------- | --------------------------------- |
| `TemplateSpec`  | The recipe (see [The template spec](#the-template-spec)), written directly or via a builder | Local until you create a template |
| `Template`      | The saved recipe and its metadata. Not a session source                                     | Until deleted                     |
| `TemplateBuild` | One execution of a recipe, with logs, events, and provenance                                | Retained with the template        |
| `Image`         | The session source a build produces, addressed by a `sha256` digest                         | Until deleted from the registry   |

Deleting a template removes its recipe and build history but leaves images it already produced launchable until you delete them from the registry.

## Build and use a template

The SDKs give you a typed builder that compiles to the canonical spec document (see [The template spec](#the-template-spec)); `createTemplate` and `buildTemplate` send it to the server.

**TypeScript**
```typescript
import { TemplateSpec, TenkiSandbox } from "@tenkicloud/sandbox";

const sandbox = new TenkiSandbox();

// 1. Define the spec (compiles to the canonical JSON document)
const spec = new TemplateSpec()
  .fromImage("sandbox")
  .withGitContext({ repo: "https://github.com/acme/node-api", ref: "main" })
  .workdir("/home/tenki/app")
  .buildEnv({ NODE_ENV: "production" })
  .run("npm ci", { timeoutSeconds: 1800 })
  .start("npm run dev", {
    runAt: "build",
    snapshotMode: "filesystem",
    readyWhen: [{ http: { url: "http://127.0.0.1:3000/health", successStatusCodes: [200, 204] } }],
  })
  .resources({ cpuCores: 2, memoryMb: 4096, diskSizeGb: 10 });

// 2. Build it. Streams events; resolves to a private, digest-addressed image
const build = await sandbox.buildTemplate(await sandbox.createTemplate({ name: "node-api", spec }), {
  buildSecrets: { GITHUB_TOKEN: token },
  waitForCompletion: true,
});

// 3. Create a session from the built image
const session = await sandbox.create({ image: build.image, waitForRuntime: true });
```

**Python**
```python
from tenki import Client, TemplateSpec

client = Client()

spec = (
    TemplateSpec()
    .from_image("sandbox")
    .with_git_context(repo="https://github.com/acme/node-api", ref="main")
    .workdir("/home/tenki/app")
    .build_env({"NODE_ENV": "production"})
    .run("npm ci", timeout=1800)
    .start("npm run dev", run_at="build", snapshot_mode="filesystem",
           ready_when=[{"http": {"url": "http://127.0.0.1:3000/health", "success_status_codes": [200, 204]}}])
    .resources(cpu_cores=2, memory_mb=4096, disk_size_gb=10)
)

template = client.templates.create(name="node-api", spec=spec)
build = client.templates.build(template, build_secrets={"GITHUB_TOKEN": token}, wait_for_completion=True)
session = client.create(image=build.image, wait_for_runtime=True)
```

**Go**
```go
import (
    "context"
    "time"

    tenkisandbox "github.com/LuxorLabs/tenki-sdk-go/sandbox"
)

ctx := context.Background()
client, err := tenkisandbox.New()

secrets := map[string]string{"GITHUB_TOKEN": "<your-token>"}

spec := tenkisandbox.NewTemplateSpec().
    FromImage("sandbox").
    WithGitContext(tenkisandbox.GitContext{Repo: "https://github.com/acme/node-api", Ref: "main"}).
    Workdir("/home/tenki/app").
    BuildEnv(map[string]string{"NODE_ENV": "production"}).
    Run("npm ci", tenkisandbox.RunStepOptions{Timeout: 1800 * time.Second}).
    Start("npm run dev", tenkisandbox.StartOptions{RunAt: tenkisandbox.RunAtBuild}).
    SnapshotMode(tenkisandbox.SnapshotModeFilesystem).
    ReadyWhen(tenkisandbox.ReadyWhen{
        Checks: []tenkisandbox.ReadyCheck{tenkisandbox.ReadyHTTP("http://127.0.0.1:3000/health", 200, 204)},
    }).
    Resources(tenkisandbox.TemplateResources{CPUCores: 2, MemoryMB: 4096, DiskSizeGB: 10})

template, err := client.CreateTemplate(ctx, tenkisandbox.WithTemplateName("node-api"), tenkisandbox.WithTemplateSpec(spec))
build, err := client.BuildTemplate(ctx, template, tenkisandbox.WithBuildSecrets(secrets), tenkisandbox.WithWaitForCompletion(true))
session, err := client.Create(ctx, tenkisandbox.WithImage(build.Image), tenkisandbox.WithWaitForRuntime(true))
```

**CLI**
```bash
# 1. Scaffold and edit .tenki/template.json (the spec shown below)
tenki template init

# 2. Build it. Waits and streams events by default; prints the digest ref
tenki template build node-api

# 3. Create a session from the built image
tenki sandbox create --image node-api
```

The session comes up in the prepared state with no install step. `--no-wait` detaches the build; `Ctrl-C` stops local streaming only and never cancels the remote build.

## Manage templates

Templates and their images are scoped to the workspace bound to your API key, so template calls don't take a workspace ID. Updating a template's typed spec is an atomic full replacement. Deleting a template leaves images it already produced launchable — remove those from the registry separately.

**TypeScript**
```typescript
const templates = await sandbox.listTemplates();
const tpl = await sandbox.getTemplate("node-api");
await sandbox.updateTemplate(tpl, { spec }); // atomic replacement of the typed recipe
await sandbox.deleteTemplate("node-api");
await sandbox.cancelTemplateBuild(buildId); // stops a remote build
```

**Python**
```python
templates = client.templates.list()
tpl = client.templates.get("node-api")
client.templates.update(tpl, spec=spec)  # atomic replacement of the typed recipe
client.templates.delete("node-api")
client.templates.cancel_build(build_id)  # stops a remote build
```

**Go**
```go
templates, err := client.ListTemplates(ctx)
tpl, err := client.GetTemplate(ctx, "node-api")
tpl, err = client.UpdateTemplate(ctx, tpl, tenkisandbox.WithTemplateSpec(spec)) // atomic replacement
_, err = client.DeleteTemplate(ctx, "node-api")
_, err = client.CancelTemplateBuild(ctx, buildID) // stops a remote build
```

**CLI**
```bash
tenki sandbox template list
tenki sandbox template get <template-id>
tenki sandbox template delete <template-id>

# Cancel the active build; use --build N when several are running
tenki template build cancel node-api
```

## The template spec

A template is a single typed document. You rarely write it by hand — the SDK builder in [Build and use](#build-and-use-a-template) and the CLI's `template init` both compile to it, and it is the canonical form the server validates, fills in with defaults, and hashes. The builder is immutable — each method returns a new spec — and every SDK can import, export, and validate a spec locally (`fromJSON`, `toJSON`, `validate`); the server rejects unknown fields and unsupported spec versions. Here is the complete spec the quickstart above produces:

```json
{
  "specVersion": "tenki.template.v1",
  "base": { "image": "sandbox" },
  "workdir": "/home/tenki/app",
  "context": {
    "source": { "git": { "repo": "https://github.com/acme/node-api", "ref": "main" } },
    "checkout": { "dest": "/home/tenki/app", "mode": "contents" }
  },
  "build": {
    "env": { "NODE_ENV": "production" }
  },
  "steps": [{ "run": { "command": "npm ci", "timeoutSeconds": 1800 } }],
  "runtime": {
    "runAt": "build",
    "start": { "command": "npm run dev", "workdir": "/home/tenki/app" },
    "snapshotMode": "filesystem",
    "readyWhen": {
      "timeoutSeconds": 60,
      "pollIntervalSeconds": 1,
      "checks": [{ "http": { "url": "http://127.0.0.1:3000/health", "successStatusCodes": [200, 204] } }]
    }
  },
  "resources": { "cpuCores": 2, "memoryMb": 4096, "diskSizeGb": 10 }
}
```

Each block maps to one part of the recipe:

| Field         | Notes                                                                                                                       |
| ------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `specVersion` | Required. Currently `"tenki.template.v1"`; the server rejects unknown or unsupported versions.                              |
| `base`        | Exactly one of a Tenki [base image](https://tenki.cloud/docs/sandbox/base-image.md) (default `sandbox`), a parent template, or a parent snapshot. |
| `workdir`     | Default `/home/tenki/app`. Used for checkout, build commands, and runtime processes.                                        |
| `context`     | The build input. A Git repo and a ref (branch, tag, or SHA), a checkout destination and mode.                               |
| `build.env`   | Plaintext environment for build steps. Not supplied to Git checkout.                                                        |
| `steps`       | Ordered operations (see below).                                                                                             |
| `runtime`     | How the application runs and when a snapshot is captured (see below).                                                       |
| `resources`   | Default vCPU (`1`–`16`), memory (`512`–`65536` MB), and disk (`5`–`100` GB) for the build and for sessions.                 |

Steps run in order and support `run`, `copy` (from the Git context to an absolute guest path), `writeFile`, `mkdir`, `remove`, `rename`, `symlink`, and the package helpers `apt`, `pip`, `npm`, and `bun`. A `run` step takes a shell command or an argv list; shell commands run under `sh -lc`, with a default timeout of 1800 seconds.

## Snapshot modes

`runtime.snapshotMode` decides what a build captures.

|                  | `filesystem` (default)                                     | `memory`                                                             |
| ---------------- | ---------------------------------------------------------- | -------------------------------------------------------------------- |
| What is captured | The disk after setup. The runtime process is stopped first | The live disk **and** memory, with the runtime process still running |
| A new session    | Boots and starts the runtime fresh                         | Restores with the process already running, for a near-instant start  |
| Requirement      | Runtime stops cleanly within the grace period              | The process must stay alive through snapshot completion              |

A snapshot is captured only for a runtime started during the build (`runAt: "build"`). If a memory image cannot be restored on a given host, Tenki cold-boots the snapshot's own disk instead of a clean base image, starts the declared runtime, and waits for the same readiness before the session is ready.

## Runtime and readiness

Runtime is optional and declares exactly one of a single `start` command or a `processCompose` configuration. For multi-process apps, `processCompose` points at a config path with an optional workdir and explicitly listed env files; Tenki owns supervision, logging, restart, and shutdown.

* **When it starts** — `runAt` is `boot` (the default when a runtime exists), `build` (started during the build so it can be snapshotted), or `manual`.
* **When it is ready** — `readyWhen` lists port, localhost HTTP, and exec checks. They run together and all must pass once. The same `readyWhen` contract applies at build time, at boot, for manual starts, and for cold-boot recovery. A build snapshot is captured only after readiness.
* **Session readiness is separate** — a session reaching `RUNNING` means the platform is ready: VM, guest agent, and networking. Application readiness has its own states — `STARTING`, `READY`, `FAILED`, `STOPPED` — and does not gate `RUNNING` or affect provisioning latency and its metrics. Opt into waiting for it with `waitForRuntime`.

## Environment and secrets

Environment variables are plaintext configuration and appear in read APIs. Set build-scoped variables under `build.env` and runtime-scoped variables under `runtime.env`.

Build secrets are different: request-time values you pass to a build for private Git checkout or secret-dependent steps. They are encrypted, carried only as an opaque reference, and never reach the runtime or appear in logs, provenance, or snapshots. The CLI reads build secrets from explicit flags and can detect `GIT_TOKEN`, `GH_TOKEN`, or `GITHUB_TOKEN`. Redaction is best-effort — a command that deliberately prints a secret can still leak it, so keep secrets out of build output. Reusable, named secret references are not yet available; pass secrets per build.

## Image references

A build produces a private image in your workspace registry, referenced three ways:

* `acme/node-api` — the untagged reference, which tracks the newest successful build.
* `acme/node-api:prod` — an optional tag you manage, a moving reference.
* `acme/node-api@sha256:…` — an immutable digest that pins the exact built output.

The digest is computed over the image's launch artifacts and behavior, so identical inputs always produce the same digest. A failed or older build never moves the untagged reference. Older `name@<snapshot-id>` references still resolve but are deprecated; new builds emit digest references only.

## Build lifecycle

A build moves through `PENDING`, `BUILDING`, `READY`, and `FAILED`. Waiting for a build streams one ordered stream of log and progress events; a waited failure raises a typed error carrying the final, redacted build. Reconnect to an in-flight build to resume streaming. Editing a template does not affect a build already in flight — each build freezes its own spec on submission.

## Build from CI

Because the spec is a single file, templates fit a GitOps flow: commit it to your repository as `.tenki/template.json` and let CI rebuild the image whenever the spec changes. The [Tenki GitHub Actions](https://github.com/LuxorLabs/tenki-actions) wrap the CLI for this — `setup-cli` installs `tenki`, and `template-build` creates or updates the template from the committed spec, builds it, and outputs the immutable digest ref.

```yaml
name: Build sandbox template

on:
  push:
    branches: [main]
    paths: [".tenki/template.json"]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: LuxorLabs/tenki-actions/setup-cli@v1
      - uses: LuxorLabs/tenki-actions/template-build@v1
        id: template
        env:
          TENKI_API_KEY: ${{ secrets.TENKI_API_KEY }}
          GITHUB_TOKEN: ${{ github.token }}
        with:
          template: node-api
      - run: tenki sandbox create --image "${{ steps.template.outputs.image }}"
```

Scaffold the spec once with `tenki template init`, then commit it. On each run, `template-build` creates the template if the name is new or replaces its spec if it already exists, waits for the build, and sets `steps.<id>.outputs.image` to the digest ref for later jobs. The `TENKI_API_KEY` secret determines the workspace the template and image belong to.

Pass build secrets — such as a token for a private Git checkout — with the `build-secret-env` input, naming job env vars to forward for that build only. The well-known `GITHUB_TOKEN`, `GH_TOKEN`, and `GIT_TOKEN` are detected automatically. See [Environment and secrets](#environment-and-secrets).

## Publish and share

The registry is a per-workspace namespace of images. Each image has a visibility: `private` (the default), `public`, or `shared` with specific workspaces. Publishing changes visibility or grants sharing; it is always explicit. Share an image across workspaces with `tenki sandbox registry share --target-workspace <workspace-id>`.

Browse and resolve images:

**TypeScript**
```typescript
const images = await sandbox.listRegistryImages({ workspace: "myworkspace" });
const image = await sandbox.getRegistryImage("myworkspace/node-api");
const resolved = await sandbox.resolveRegistryRef("myworkspace/node-api:prod");
```

**Python**
```python
images = client.registry.list("myworkspace")
image = client.registry.get("myworkspace/node-api")
resolved = client.registry.resolve("myworkspace/node-api:prod")
```

**Go**
```go
images, err := client.ListRegistryImages(ctx, tenkisandbox.WithRegistryWorkspace("myworkspace"))
image, err := client.GetRegistryImage(ctx, "myworkspace/node-api")
resolved, err := client.ResolveRegistryRef(ctx, "myworkspace/node-api:prod")
```

**CLI**
```bash
tenki sandbox registry list --workspace myworkspace
tenki sandbox registry get myworkspace/node-api
tenki sandbox registry resolve myworkspace/node-api:prod
```

## Not supported

A few things are out of scope today:

* Local filesystem or archive build contexts — the build context is Git only.
* Launching a session from an inline recipe file — the template must exist as a resource first. Once it does, you can either build it into an image or launch a session directly from its stored spec with `tenki sandbox create --from-template-spec <name-or-id>`.
* Dockerfile ingestion and full devcontainer features.
* Per-build overrides for Git ref, environment, or resources.
* Automatic public or shared publishing, and turning build numbers into tags — visibility and tags are always explicit.

## Errors

Template and registry calls fail when a reference is unknown, a build fails, or a name collides. Every SDK surfaces these as typed errors or exceptions; see the [SDK reference](https://tenki.cloud/docs/sandbox/sdk.md#errors) for the names in each language.

# Troubleshooting (https://tenki.cloud/docs/sandbox/troubleshooting)

Diagnose common Tenki Sandbox issues including session creation hangs, missing volume data after restore, SSH errors, port exposure, and command timeouts.

If something isn't working as expected, walk through the relevant section below before reaching out. Most issues come down to one of: auth, validation limits, attached resources not re-attached after restore, or the guest application itself.

## Session creation hangs or never becomes RUNNING

Check, in order:

1. **Endpoint**: is `TENKI_API_URL` (or `WithBaseURL`) pointing at the right environment?
2. **Auth token**: is `TENKI_API_KEY` set, valid, and not expired?
3. **Resource limits**: is `--cpu` between `1` and `16` and `--memory-mb` between `128` and `65536`?
4. **Snapshot**: if you passed `--snapshot`, does it have a `READY` state?

Inspect the session record directly:

```bash
tenki sandbox get --session <session-id> --json
```

## Snapshot restore works but data from a prior volume is missing

That is **expected** unless you re-attach the volume. Snapshots do not automatically restore prior volume attachments.

Re-attach explicitly:

```bash
tenki sandbox create --snapshot <snapshot-id> --volume <volume-id>:/workspace/cache
```

Or after the session is up:

```bash
tenki sandbox volume attach <session-id> <volume-id> --mount /workspace/cache
```

## SSH fails

Check:

* the session still exists and is `RUNNING` (`tenki sandbox get --session <session-id>`)
* your keys were added at create time (`--authorized-key` / `--authorized-keys-file`) or via `ssh-keys set`
* if you're using the managed SSH config, run `tenki sandbox ssh config status` to verify the assets are installed
* the session was created with inbound enabled if your environment requires it

Reset the authorized keys to a known-good set:

```bash
tenki sandbox ssh-keys set --session <session-id> --keys-file ~/.ssh/authorized_keys
```

## Port exposure fails

Check:

1. **The app is actually listening inside the guest.** Verify with `tenki sandbox exec ... -c 'ss -tlnp'`.
2. **The right port is exposed.** `tenki sandbox ports --session <session-id>` lists the active set.
3. **Inbound is allowed.** The session must have been created with `--allow-inbound`. You cannot toggle inbound after create.

Don't hard-code preview hostnames in client code. Always use the `preview_url` returned by `expose`.

## Command execution times out

Increase the timeout:

```bash
tenki sandbox exec --session <session-id> --timeout 5m -c 'long-running-command'
```

```go
result, err := session.Exec(
  ctx,
  "bash",
  tenkisandbox.WithArgs("-lc", "long-running-command"),
  tenkisandbox.WithTimeout(5*time.Minute),
)
```

If you need to keep running an unbounded process, run it in the background inside the guest (`nohup ... &` or a systemd unit if your base image provides one) and poll for completion with subsequent exec calls.

## exec reports flag provided but not defined: -lc

`exec` parses its own flags first, so `-lc` is read as a CLI flag rather than a shell argument. To run a shell one-liner, use `-c` (`tenki sandbox exec -c '...'`). To pass flags straight to a specific program, put them after `--` so the CLI stops parsing its own flags (`tenki sandbox exec -- bash -lc '...'`).

## exec hangs when starting a background server

`exec` streams the command's stdout and stderr until they close. A process backgrounded with a bare `&` still holds those streams open, so `exec` waits for it forever (for example `python3 -m http.server 3000 &` never returns).

Redirect the background process's output and detach its stdin so it no longer holds the stream:

```bash
tenki sandbox exec -c 'python3 -m http.server 3000 >/tmp/server.log 2>&1 </dev/null &'
```

`exec` returns as soon as the foreground shell exits, and the server keeps running. Then `tenki sandbox expose --port 3000`.

## Auth errors

| Symptom               | Likely cause                                          |
| --------------------- | ----------------------------------------------------- |
| `ErrUnauthorized`     | missing or malformed token; API keys start with `tk_` |
| `ErrPermissionDenied` | token authenticates but lacks the required scope      |
| `ErrRateLimited`      | back off and retry with jitter                        |
| `ErrQuotaExceeded`    | workspace has hit a resource quota; contact us        |

## Volume errors

| Symptom                  | Likely cause                                        |
| ------------------------ | --------------------------------------------------- |
| `ErrVolumeNotFound`      | wrong workspace, or volume was deleted              |
| `ErrVolumeInUse`         | volume is attached to another session; detach first |
| `ErrVolumeLimitExceeded` | workspace volume quota; delete unused volumes       |

CLI rejects bare numeric sizes:

```bash
# rejected
tenki sandbox volume create ... --size 1024

# accepted
tenki sandbox volume create ... --size 10GB
tenki sandbox volume create ... --size 10GiB
```

## Still stuck?

Email us at [hello@tenki.cloud](mailto:hello@tenki.cloud) with:

* the session or snapshot ID
* the CLI command or SDK call you ran
* the full error message
* the time of the failure

> **Don't paste API keys:** When sharing logs or commands with support, scrub `TENKI_API_KEY` and any `tk_` tokens. Replace and revoke the key from the API Keys screen if it ever leaves your machine.

# Persistent Volumes (https://tenki.cloud/docs/sandbox/volumes)

Use Tenki Sandbox persistent volumes for durable build caches, package caches, large repositories, and datasets that survive session termination.

Persistent volumes are workspace-scoped block storage that survives the session it was used in. Volumes are the right tool for **durable data**: package caches, build caches, large repos, datasets, anything you want available across many sessions.

## Volume lifecycle

Pick your tool, and the selection syncs across the rest of the page.

### Create

**CLI**
```bash
tenki sandbox volume create --name npm-cache --size 20GB
```

The CLI requires explicit units:

* `10GB`, `10GiB`, `500MB`: accepted
* bare `1024`: rejected

**TypeScript**
```typescript
import { GiB } from "@tenkicloud/sandbox";

const volume = await sandbox.createVolume({
  name: "data-vol",
  sizeBytes: 10 * GiB,
});

await sandbox.waitVolumeReady(volume.id);
```

**Go**
```go
volume, err := client.CreateVolume(
  ctx,
  tenkisandbox.WithVolumeName("npm-cache"),
  tenkisandbox.WithVolumeSize(20*tenkisandbox.GB),
)

volume, err = client.WaitVolumeReady(ctx, volume.ID, 3*time.Minute)
```

Useful size constants: `tenkisandbox.KB`, `MB`, `GB` (and `KiB`, `MiB`, `GiB` for binary units).

**Python**
```python
from tenki import Client, GiB

client = Client()

volume = client.volumes.create(
    name="npm-cache",
    size_bytes=20 * GiB,
)

volume = client.volumes.wait_ready(volume.id, timeout=180)
```

Size constants are exported at the top level: `KB`, `MB`, `GB` (and `KiB`, `MiB`, `GiB` for binary units).

Volumes can be between `1 MiB` and `100 GiB`.

### List, get, resize, delete

**TypeScript**
```typescript
const volumes = await sandbox.listVolumes();
const volume = await sandbox.getVolume(volumeId);
await sandbox.resizeVolume(volumeId, 40 * GiB);
await sandbox.deleteVolume(volumeId);
```

**Python**
```python
volumes = client.volumes.list()
volume = client.volumes.get(volume_id)
volume = client.volumes.resize(volume_id, 40 * GB)
client.volumes.delete(volume_id)
```

**Go**
```go
volumes, err := client.ListVolumes(ctx)
volume, err := client.GetVolume(ctx, volumeID)
volume, err = client.ResizeVolume(ctx, volumeID, 40*tenkisandbox.GB)
err = client.DeleteVolume(ctx, volumeID)
```

**CLI**
```bash
tenki sandbox volume list
tenki sandbox volume list --json
tenki sandbox volume get <volume-id>
tenki sandbox volume resize <volume-id> --size 40GB
tenki sandbox volume delete <volume-id>
```

## Attach to sessions

### Attach at create time

**CLI**
```bash
tenki sandbox create \
  --volume <volume-id>:/workspace/cache \
  --volume <other-id>:/workspace/reference:ro
```

The optional `:ro` suffix mounts the volume read-only.

**TypeScript**
```typescript
const session = await sandbox.createAndWait({
  volumes: [
    { volumeId: cacheVolumeId, mountPath: "/workspace/cache" },
    { volumeId: refVolumeId, mountPath: "/workspace/reference", readOnly: true },
  ],
});
```

**Go**
```go
session, err := client.Create(
  ctx,
  tenkisandbox.WithVolume(cacheVolumeID, "/workspace/cache"),
  tenkisandbox.WithVolume(refVolumeID, "/workspace/reference", tenkisandbox.WithReadOnly()),
)
```

**Python**
```python
sb = Sandbox.create(
    volumes=[
        {"volume_id": cache_volume_id, "mount_path": "/workspace/cache"},
        {"volume_id": ref_volume_id, "mount_path": "/workspace/reference", "read_only": True},
    ],
)
```

### Attach to a running session

**CLI**
```bash
tenki sandbox volume attach <session-id> <volume-id> --mount /workspace/cache
tenki sandbox volume attach <session-id> <volume-id> --mount /workspace/reference --readonly
tenki sandbox volume detach <session-id> <volume-id>
```

**TypeScript**
```typescript
await session.attachVolume(volume.id, "/mnt/data");
await session.detachVolume(volume.id);
```

**Go**
```go
err := session.AttachVolume(ctx, volumeID, "/workspace/cache")
err = session.AttachVolume(ctx, refVolumeID, "/workspace/reference", tenkisandbox.WithReadOnly())
err = session.DetachVolume(ctx, volumeID)
```

**Python**
```python
sb.attach_volume(volume_id, "/workspace/cache")
sb.attach_volume(ref_volume_id, "/workspace/reference", read_only=True)
sb.detach_volume(volume_id)
```

## Workspace scope

Volumes belong to the workspace bound to your API key. Create and list calls infer that workspace, so do not pass
a workspace ID.

## Snapshots and volumes

Snapshots do not auto-reattach a session's volumes. A restored session is a normal session, so reattach any volume explicitly, at create time or with `volume attach`. See [Snapshots](https://tenki.cloud/docs/sandbox/snapshots.md) for the restore workflow.

Keep durable data in volumes, not snapshots: baking a cache or dataset into a snapshot bloats it and ties that data to one VM's history.

## Errors to handle

Volume calls can fail with a not-found, in-use, or quota error. The one worth handling is in-use: the volume is still attached to another session, so detach it from that session or wait, then retry. Every SDK surfaces these as typed errors or exceptions; see the [SDK reference](https://tenki.cloud/docs/sandbox/sdk.md#errors) for the names in each language.

# Security & Isolation (https://tenki.cloud/docs/trust/security)

How Tenki isolates customer workloads and secures CI infrastructure, operating under the SOC 2 Type II program of its parent company Luxor.

Security at Tenki rests on three pillars: **ephemeral per-job VMs**, **isolation enforced at the hypervisor layer**, and **an audited compliance posture inherited from our parent company, Luxor**.

## Ephemeral, single-use VMs

Every job, Linux x64 or macOS, runs in a fresh VM that is provisioned at job start and destroyed at job end. VMs are never reused across jobs or across customers. There is no persistent state on the runner between jobs.

This is the property mobile-signing and supply-chain-sensitive teams typically require. Confirmed properties:

* New filesystem on every job
* No shared memory or process space between jobs
* VM teardown happens immediately on job completion, regardless of success or failure
* No background workload reuses the VM

## Isolation model

| Runner family | Compute                                                  | Isolation                                               |
| ------------- | -------------------------------------------------------- | ------------------------------------------------------- |
| Linux x64     | Bare-metal AMD EPYC compute, owned and operated by Tenki | Each job runs in a dedicated VM                         |
| macOS M4 Pro  | Apple Silicon hardware in our fabric                     | Each job runs in an isolated VM destroyed on completion |

macOS hardware is multi-tenant at the hardware level (resources are shared across customers), but jobs themselves always run in isolated VMs that are destroyed after each job. There is no shared filesystem, no shared keychain, and no shared user account between jobs.

## Secrets

Tenki does **not** operate a secrets store. Secrets are managed by GitHub Actions and injected into the job at runtime through the standard `secrets.*` mechanism. See [Secrets](https://tenki.cloud/docs/runners/secrets-and-signing.md) for more on the ephemeral-VM model.

## Compliance

Tenki is operated by **Luxor**, a company founded in **2017** that is profitable and cash-flow positive with over 100 employees. Luxor holds:

* **SOC 1 Type II**, renewed annually
* **SOC 2 Type II**, renewed annually
* Yearly audited financial statements

Most of Luxor's largest customers are publicly traded companies operating in the data-center (Bitcoin mining / AI-HPC) space, with the security and compliance bar that implies.

Tenki operates under the SOC 2 Type II program of its parent company Luxor.

> **Need a SOC 2 Type II report?:** Tenki operates under the SOC 2 Type II program of its parent company Luxor Technology; the report is available under NDA — email hello@tenki.cloud to request it.

## GitHub App scopes

The two Tenki GitHub Apps (Runner and Code Reviewer) request the minimum permissions required for their respective functions. See [GitHub App access levels](https://tenki.cloud/docs/github/gh-app-access-level.md) for the full permission table and the rationale for each scope.

# Tenki vs Blacksmith (https://tenki.cloud/docs/runners/comparisons/tenki-vs-blacksmith)

How Tenki and Blacksmith compare on price, performance, free tier, macOS support, and migration.

## Tenki vs Blacksmith: at a glance

Tenki and Blacksmith are both bare-metal GitHub Actions runner providers that position themselves as faster, cheaper drop-in replacements for GitHub-hosted runners. The biggest practical differences are product scope (Tenki includes an AI code reviewer; Blacksmith is runner-only), hardware footprint (Tenki runs both x64 and Apple Silicon M4 Pro; verify Blacksmith's current macOS lineup on its site), and free-tier generosity.

## How we compared

* **Sources**: Tenki numbers come from this site's product, pricing, and docs pages. Blacksmith numbers come from [blacksmith.sh](https://www.blacksmith.sh) and Blacksmith's public documentation, captured on the "Last updated" date shown above the table of contents.
* **Pricing**: Tenki's $0.004/min standard rate (a 2 vCPU runner at $0.002 per core/minute) comes from this site's pricing and docs pages. Where Blacksmith's pricing depends on plan or profile, we link to Blacksmith's pricing page rather than restating numbers that may differ across plans.
* **Hardware**: Tenki's hardware claims come from this site's product and docs pages. Blacksmith's macOS availability is hedged ("verify on its site") because the Blacksmith fleet is documented as evolving — we'd rather link than freeze a snapshot that goes stale between updates.
* **Performance**: this page does not run head-to-head perf benchmarks. Tenki's runner numbers are documented separately in [the runner benchmarks](https://tenki.cloud/docs/runners/benchmarks.md) with full methodology (hardware, baseline, cache state, sample size). Blacksmith's performance claims are restated from Blacksmith's marketing copy where cited.
* **Updates**: re-verified each quarter and on every update to this page. Changes are visible via the `dateModified` shown above and in this repository's git history.

## Quick comparison

| Dimension             | Tenki                                                    | Blacksmith                                             |
| --------------------- | -------------------------------------------------------- | ------------------------------------------------------ |
| Core product          | Runners + AI code reviewer                               | Bare-metal GitHub Actions runners                      |
| Hardware              | Bare-metal x64 and Apple Silicon M4 Pro                  | Bare-metal x64 (verify current macOS offering)         |
| Standard runner price | $0.004/min (2 vCPU / 4 GB Linux)                         | See [blacksmith.sh](https://www.blacksmith.sh) pricing |
| Free tier             | $10 in free credit per month, renewed monthly            | See Blacksmith's current free-tier terms               |
| macOS runners         | Apple M4 Pro bare-metal                                  | Check availability                                     |
| Isolation             | Fresh single-tenant VM per job, own kernel, never reused | VM-level isolation                                     |
| AI code review        | Included (Tenki Code Reviewer, $1.00 per review)         | Not offered                                            |
| Migration effort      | One-line `runs-on` change                                | One-line `runs-on` change                              |

## When to choose Tenki

* You want a single vendor for runners and AI pull-request review.
* You need Apple M4 Pro macOS runners alongside Linux.
* You want a fresh single-tenant VM per job, never reused across jobs or customers.
* You want $10 in free credit every month for evaluation.

## When to choose Blacksmith

* You want a runner-only vendor with no adjacent products.
* Blacksmith's specific hardware or region lineup matches your regulatory needs better than Tenki's.

## Migration

Both vendors support a one-line `runs-on` change in your workflow YAML. Migrating to Tenki:

```yaml
jobs:
  build:
    runs-on: tenki-standard-medium-4c-8g # was: ubuntu-latest or blacksmith-*
```

See the [Runners Quickstart](https://tenki.cloud/docs/runners/quickstart.md) for full setup including the two-click Migration Wizard.

## FAQ

### Is Tenki faster than Blacksmith?

Both vendors run on bare-metal hardware, so performance depends on the specific workload and profile. Tenki publishes [runner benchmark numbers](https://tenki.cloud/docs/runners/benchmarks.md), we recommend running your own benchmark on a workload that matters to you on both vendors' free tiers.

### Is Tenki cheaper than Blacksmith?

Tenki's standard 2 vCPU / 4 GB Linux runner is $0.004 per minute. Compare against Blacksmith's current [published rates](https://www.blacksmith.sh) for the same profile.

### Can I switch from Blacksmith to Tenki?

Yes. Change the `runs-on:` value in your workflow YAML and run Tenki's Migration Wizard to set up the GitHub App. No other workflow changes are needed.

### Does Tenki offer AI code review like a separate add-on?

AI code review is a separate Tenki product (Tenki Code Reviewer) priced at $1.00 per review, drawn from your Tenki workspace credit balance. It can be used independently of Tenki runners.

# Tenki vs Depot (https://tenki.cloud/docs/runners/comparisons/tenki-vs-depot)

How Tenki and Depot compare on price, performance, free tier, macOS support, and migration.

## Tenki vs Depot: at a glance

Tenki and Depot both offer faster-than-GitHub CI infrastructure, but solve slightly different problems. Tenki is a full drop-in replacement for GitHub-hosted runners built on bare-metal x64 and Apple Silicon M4 Pro hardware, priced at $0.004 per minute for a 2 vCPU / 4 GB standard runner, with $10 in free credit per month for every workspace. Depot began as a faster Docker-image builder with distributed remote caching and later added GitHub Actions runners; its focus remains Docker-first workflows and build caching.

This page summarises the practical differences so you can choose the right tool for your workload.

## How we compared

* **Sources**: Tenki numbers come from this site's product, pricing, and docs pages. Depot numbers come from [depot.dev/pricing](https://depot.dev/pricing), [depot.dev/products/github-actions](https://depot.dev/products/github-actions), and Depot's public documentation, captured on the "Last updated" date shown above the table of contents.
* **Pricing**: we cite Tenki's standard 2 vCPU / 4 GB Linux per-minute rate verbatim. Where Depot's pricing depends on profile selection, we link to Depot's pricing page rather than restating a number that may differ across plans.
* **Performance**: this page does not run head-to-head perf benchmarks. Tenki's runner numbers are documented separately in [the runner benchmarks](https://tenki.cloud/docs/runners/benchmarks.md) with full methodology (hardware, baseline, cache state, sample size). Depot's performance claims are restated from Depot's marketing copy where cited.
* **Updates**: we re-verify Depot's pricing and product scope each quarter and on every update to this page. Changes are visible via the `dateModified` shown above and in this repository's git history.

## Quick comparison

| Dimension             | Tenki                                                    | Depot                                                                   |
| --------------------- | -------------------------------------------------------- | ----------------------------------------------------------------------- |
| Core product          | Full GitHub Actions runner replacement                   | Remote Docker build cache + GitHub Actions runners                      |
| Hardware              | Bare-metal x64 and Apple Silicon M4 Pro                  | AWS bare-metal / EC2                                                    |
| Standard runner price | $0.004/min (2 vCPU / 4 GB Linux)                         | See [depot.dev/pricing](https://depot.dev/pricing)                      |
| Free tier             | $10 in free credit per month, renewed monthly            | See Depot's current free-tier terms                                     |
| macOS runners         | Apple M4 Pro bare-metal                                  | Linux-first; check availability                                         |
| Isolation             | Fresh single-tenant VM per job, own kernel, never reused | Build-sandbox per job                                                   |
| Primary pitch         | Full workflow replacement with bare-metal perf           | Fastest Docker builds with shared remote cache                          |
| Migration effort      | One-line `runs-on` change                                | One-line `runs-on` change (for runners); separate setup for build cache |
| AI code review        | Included product (Tenki Code Reviewer)                   | Not offered                                                             |

## When to choose Tenki

* You want to replace GitHub-hosted runners wholesale with bare-metal capacity.
* You need macOS runners (M4 Pro) alongside Linux.
* You want a full runner VM per job rather than a build-scoped sandbox.
* You want AI-powered pull-request review as part of the same product.
* You want $10 in free credit every month to evaluate.

## When to choose Depot

* Docker image builds are your bottleneck and you want an optimised remote build cache.
* You're already invested in Depot's caching layer and want to consolidate runners with it.
* You need AWS-hosted runners for regulatory or data-gravity reasons.

## Migration

Migrating to Tenki takes one line in your workflow YAML:

```yaml
jobs:
  build:
    runs-on: tenki-standard-medium-4c-8g # was: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - run: ./scripts/build.sh
```

No other workflow changes are required. See the [Runners Quickstart](https://tenki.cloud/docs/runners/quickstart.md) for the full walkthrough including the two-click Migration Wizard.

## FAQ

### Is Tenki cheaper than Depot?

On the standard 2 vCPU / 4 GB Linux profile, Tenki is $0.004 per minute. Depot's current pricing is published at [depot.dev/pricing](https://depot.dev/pricing), compare the specific profile you run. Both are substantially cheaper than GitHub-hosted runners.

### Can I use Tenki and Depot together?

Yes. Tenki's runners work with any third-party GitHub Action, including Depot's build-cache actions. The two are not mutually exclusive.

### Does Tenki support macOS?

Yes. Tenki operates Apple M4 Pro bare-metal macOS runners for iOS, macOS, and cross-platform CI/CD workflows. Depot's macOS availability should be checked on its pricing page.

### How does isolation differ?

Tenki runs every job in an ephemeral VM that is destroyed immediately after the job finishes, no persistent state between runs, no noisy-neighbor interference. Depot uses its own build-sandbox per job.