Skip to main content

The loop in CI

CI is where drift is made: every merge changes source content and leaves its translations, terminology, and brand conformance behind. It is also the natural place to catch up. The kapi loop runs on every change or on a schedule; what a machine cannot decide parks into the team's review queue on the server; and the ship gate protects releases without ever failing an ordinary build on target-language drift.

On a project connected to a Bowrain server, a CI run of kapi up executes on the server venue: the job pushes the drift, the server runs the loop on the organization's AI keys, shared content memory, and terminology, and the results come back to the working tree. The runner holds a server token and no provider keys.

This page maps the surfaces and the contract they share. The step-by-step generic walkthroughs — scheduling, gating, cost reporting on GitHub and GitLab — live on the kapi site: The kapi loop in CI.

Your pipeline produceskapi-action · kapi-components · ghcr imagea merge or a schedule tickkapi up — the loop runs on the servera PR/MR with the run reportYour pipeline gateskapi check --shipa merge request opensthe bound gates runexit 3 blocks the mergeNo pipelineforge connector · Bowrain GitHub Appa push webhook reaches the serverthe server re-ingests and convergesone PR/MR, updated in place

Produce and gate from your own CI, or let the server do both with no pipeline at all.

The contract

Three commands divide the work, and their exit codes are the whole interface a pipeline needs:

CommandRoleExit behavior
kapi statusObserve — per-locale coverage and gate standingAlways 0: behind is pending work, not an error
kapi upProduce — runs the kapi loop0 whether the run caught everything up or parked work for review; non-zero only when the run broke
kapi check --shipEnforce — the release bar0 pass, 3 gate unmet, 1 operational error

Parked work is pending review, not an error. The gate is the explicit, opt-in enforcement point — wire it into merge-request pipelines and a quality regression cannot merge, while day-to-day drift flows through review instead of breaking builds.

The surfaces

SurfaceHow it runsGuide
GitHub Actionssetup-kapi installs the CLI (the bowrain plugin included by default); kapi-action runs kapi up and commits or opens a pull request. The reusable kapi-workflows (up.yml@v1, gate.yml@v1) compose both into one-line jobsGitHub Actions
GitLab CIkapi-components from the CI/CD Catalog: up delivers a merge request, check gates merge-request pipelinesGitLab CI
Any container runnerghcr.io/neokapi/kapi (cosign-signed; the server-sync plugin is preinstalled, so kapi up / push / pull work out of the box) and the CLI directly — the exit codes above are the contractthis page
No pipelineThe forge connector / Bowrain GitHub App: the server converges on every push to the tracked branch and delivers the results back as one PR/MRThe Bowrain GitHub App

Which to use when

If you own the repository's CI and want control over triggers, delivery, and gating, use kapi-action on GitHub or kapi-components on GitLab — each job is an ordinary pipeline step you can shape. For minimal setup on GitHub, the reusable workflows give you the whole produce-and-deliver or gate job as a single uses: line. When nobody owns the repository's CI — a docs, marketing, or content repository — or you want zero configuration in the repository at all, connect it server-side with the forge connector or the Bowrain GitHub App: the server converges on every push and delivers a pull request back on its own.

Authenticating a runner

Mint a CI token once, from an authenticated machine:

kapi auth login
kapi auth token create --name "ci" --expire-days 90

The token (bwt_…) is shown once — store it as a CI secret immediately. On the runner, BOWRAIN_AUTH_TOKEN carries the credential, and the CLI checks it before any stored login:

BOWRAIN_AUTH_TOKEN=bwt_...
BOWRAIN_SERVER_URL=https://bowrain.example.com # self-hosted only

BOWRAIN_SERVER_URL is only needed for a self-hosted server: the hosted service (https://app.bowrain.cloud) is the built-in default, and project commands (kapi up, push, pull, check) read the server from the checked-out recipe's server: block in any case. On GitHub Actions, setup-kapi's auth-token and server inputs export exactly these two variables. On GitLab, set them as masked CI/CD variables. List and revoke tokens with kapi auth token list and kapi auth token delete.

What a job needs beyond the server token depends on its venue:

  • Server venue (a connected project) — nothing. The server holds the AI keys; the job only pushes, watches, and pulls.
  • Local venue (kapi up --local, or a project with no server: block) — the loop runs inside the job and needs a provider key, for example ANTHROPIC_API_KEY, as a CI secret.
  • Gate-only jobskapi check --ship reads the working tree and needs no AI keys; when the gate enforces governed terminology, the job runs kapi pull first and needs the server token. See Gate brand terminology in CI.

Next