Skip to content
CloseYourItdocsPages

Documentation / AI and automation

Automator

Let tickets be worked automatically on your own Linux machine, with Claude Code, Codex or both.

The automator takes the tickets you allow, works them in an isolated folder of the repository, and opens a change for review. It runs on your machine, with your subscription: the code never leaves it.

Requirements

  • Linux x86_64 or arm64 with systemd 254 or newer.
  • bubblewrap and socat, used to confine what the agent can write and where it can connect. Without socat, Claude Code does not start.
  • A system keyring (gnome-keyring) with a «login» collection: the automator keeps the machine's token there.
  • Codex, installed and signed in: always required, because Claude's review also runs inside the Codex sandbox. Without Codex no work is reviewed and none reaches a PR.
  • Claude Code, if you want Claude to work or review.
  • Install Codex with the user's npm (for example the one from mise), not with sudo npm -g: the automator does not run programs from /usr/lib, nor from folders other users can change.

automator doctor checks every requirement and says what is missing.

Ubuntu 24.04 and newer

Ubuntu blocks the isolation bubblewrap needs, so the sandbox does not start. Allow it once with an AppArmor profile:

sudo tee /etc/apparmor.d/bwrap >/dev/null <<'PROFILE'
abi <abi/4.0>,
include <tunables/global>

profile bwrap /usr/bin/bwrap flags=(unconfined) {
  userns,
  include if exists <local/bwrap>
}
PROFILE
sudo apparmor_parser -r /etc/apparmor.d/bwrap

A server without a desktop needs two more steps.

Install socat and the keyring:

sudo apt install socat gnome-keyring libsecret-tools

Create the keyring's «login» collection, as the user that will run the automator. Without it, installation stops with credential store vault non disponibile:

pkill -u "$(id -u)" gnome-keyring-d
printf '\n' | gnome-keyring-daemon --unlock --components=secrets --daemonize

Connect a machine

  1. In the app: Automator → Connect a machine.
  2. Copy the command and run it on the machine.

Who does the work

Choose it per machine in Automator → the machine → Who does the work: Claude (the default) or Codex. The machine must have that engine installed and signed in.

On a machine with Codex only, also set AUTOMATOR_WORK_ENGINE=codex in the service environment: setup and doctor then ask for Codex instead of Claude.

Both engines work under the same limits:

  • writes only in the ticket's folder, and in the Git data that its commits need;
  • network only to CloseYourIt, GitHub, npm and RubyGems;
  • no push to protected branches, no production commands, no destructive database commands.

Who reviews the work

Every piece of work is read again before it reaches you. Choose it per machine in Automator → the machine → Who reviews the work:

  • The other engine — Codex reviews Claude's work and Claude reviews Codex's. Both must be on the machine. This is the default.
  • The same engine — the engine reviews its own work in a new session. One engine is enough.

Models

The automator uses a fixed model for each engine, so an update of the CLI never changes it by surprise. To use another one, set it in the service environment:

VariableDefault
AUTOMATOR_CLAUDE_MODELclaude-opus-5-5
AUTOMATOR_CODEX_MODELgpt-6-astra

Your server and your production

Two settings of the service environment tell the automator about your installation. Set them before automator setup, and keep them the same for the service and for the commands you run by hand: they are part of the guardrails, which refuse to start if they change behind their back.

VariableWhat it does
AUTOMATOR_SANDBOX_DOMAINSExtra domains the sandbox may reach, comma-separated. Put your CloseYourIt here, for example tracker.example.com; GitHub, npm and RubyGems are already allowed.
AUTOMATOR_PRODUCTION_HOSTSYour production hosts and addresses, comma-separated. The automator refuses ssh, scp, rsync and database URLs towards them.

A malformed entry stops the automator instead of being skipped, so a typo never leaves a host unprotected.