autofeat docs
Use autofeat

Quickstart

Ten-minute path from an empty repository to the first autofeat check run.

Use the hosted App. Do this once per repository. Keep one path: if .github/workflows/autofeat.yml exists, remove it first. See Actions path.

The portal at https://portal.autofeat.app can do steps 3, 4, and 5 for you (config pull request, labels, and the state ruleset).

1. Install the App

Install autofeat-axc on this repository only:

https://github.com/apps/autofeat-axc/installations/new

Choose Only select repositories and add the repository.

The App is public. App id 5103856. Permissions: contents write, pull requests write, issues write, checks write, statuses read, metadata read.

2. Wait for operator approval

Webhooks are ignored until an operator allowlists both the installation id and owner/repo (lower case). The portal shows waiting for operator approval until both appear in the operator control list.

Without that allowlist, labelling a pull request does nothing.

3. Add .autofeat/config.yml on the default branch

Commit this file on the default branch. The worker reads that branch head only. A pull request cannot change its own policy.

version: 1
identity: app
entry_action: review
autonomy:
  merge_target: main
  merge_mode: stop_before_merge
  auto_approve: false
  dry_run: true
  require_green_checks: true
policy:
  mode: review_only
agents:
  default: claude
  allowed: [claude, codex, kimi, grok-build]
  billing: {claude: subscription, codex: subscription, kimi: subscription, grok-build: subscription}
  models: {claude: {model: sonnet}}
budget:
  turns: 12
  usd: 25.0
  alert_usd: 10.0
  minutes: 240
security:
  require_signature: true
  trusted_actors: [OWNER]

Replace main if your default branch has another name. Replace OWNER with the GitHub login autofeat should trust for signed directives. dry_run: true writes the journal, the sticky comment, and check runs. It does not push, review, merge, or change labels.

The full key list is Configure.

4. Create the four labels

Colours are the first 6 hex digits of SHA-256 of the key go, stop, pause, and ready. That is what autofeat init writes.

gh label create "autofeat:go" --color 4cd0e2 --repo OWNER/REPO --force
gh label create "autofeat:stop" --color 6c45cb --repo OWNER/REPO --force
gh label create "autofeat:pause" --color 6210c0 --repo OWNER/REPO --force
gh label create "autofeat:ready" --color b24d6d --repo OWNER/REPO --force

Meanings: Labels.

5. Create the state ruleset

The journal lives on refs/heads/autofeat-state/pr-<N>. This ruleset blocks deletion and non-fast-forward updates. You need administration on the repository. bypass_actors stays empty.

gh api \
  --method POST \
  -H "Accept: application/vnd.github+json" \
  /repos/OWNER/REPO/rulesets \
  --input - <<'EOF'
{
  "name": "autofeat-state-refs",
  "target": "branch",
  "enforcement": "active",
  "bypass_actors": [],
  "conditions": {
    "ref_name": {
      "include": ["refs/heads/autofeat-state/**"],
      "exclude": []
    }
  },
  "rules": [
    {"type": "deletion"},
    {"type": "non_fast_forward"}
  ]
}
EOF

6. Open a pull request and add autofeat:go

Write the spec in the pull request body. See Write a spec. Add the label autofeat:go.

You should see, in order:

  1. Check run autofeat/review on the head SHA. Status moves from queued to in_progress to completed.
  2. A sticky comment whose body starts with <!-- autofeat:state -->. See Reading the state comment.
  3. A journal ref refs/heads/autofeat-state/pr-<N>.

With dry_run: true the check conclusion is neutral. Go paid only after a clean dry run. See Budgets and billing.

If nothing happens, see Troubleshooting.

On this page