---
name: talooner-onboard
description: Onboard the current repository to Talooner — interview the user, write the onboarding spec (.talooner/onboarding.md), write or sharpen the guides the AI review checks code against (docs/guides/*.md, linked in .talooner/architecture.yaml), build .talooner/rules.tln and its .tln.test suite from it with the talooner-runner image, tailor the rules to this codebase, keep the tests green, and prepare a pull request. Use when the user asks to onboard a repo to Talooner, set up Talooner rules, or add a Talooner PR guard.
---

# Onboard a repository to Talooner

Talooner reviews every pull request against the policy in `.talooner/rules.tln`. This
skill works spec-first: you ask the user a few questions, write their answers to
`.talooner/onboarding.md`, and onboarding builds the rules from that spec. Then you adapt
the rules to the code and leave everything ready to commit. Docs: https://talooner.dev/onboard/

```
IMAGE=ghcr.io/talooner/talooner-runner:latest
```

## tln in one minute

Rules are written in **tln** — an open language for deterministic rules. Full reference:
https://tln-lang.org/ (read it before writing anything beyond the patterns below).

```tln
define "critical_path" {                 // a named predicate
  attr "pr.changed_files" contains "internal/auth/"
    or attr "pr.changed_files" contains "billing/"
}

rule "Auth changes need a security review" {
  for records where type == "pr" and is "critical_path"
  requires "review.security"             // verdict: allow | block "…" | requires "…"
  do block "pr.merge"                    // what actually holds the merge (see below)
  do require "review.security"           // what requests the reviewers
  do comment "pr" "Touches auth — security review requested"
  reason "critical path"
  priority HIGH
}
```

- A `rule` matches records (`for records where …`) on PR facts (`attr "pr.…"`) and named
  predicates (`is "…"`), declares a verdict, and lists actions with `do …`
  (`approve`, `block`, `comment`, `require`, `assign`, `llm_review`).
- `requires "…"` only names the review a rule wants — it has no effect on its own. Pair
  it with `do block "pr.merge"` (and `do require "…"`) whenever the PR must wait.
- Don't write `strict` rules: Talooner loads its own strict base ruleset into every
  repository, and declaring one of its rule names again is a compile error. Don't use
  `do notify` either — it has no executor yet, and a fired notify fails the whole run.
- Common facts: `pr.lines_changed`, `pr.files_changed`, `pr.changed_files`, `pr.draft`,
  `pr.has_description`, `pr.tests_passing`, `pr.is_fork`, `pr.new_dependencies`,
  `pr.author`, `user.owner` (from CODEOWNERS, else the last person to touch the code).
- An unset fact fails closed: a condition on it is simply false. `pr.tests_passing` is
  only set once CI reports the checks Talooner is configured to read.
- Tests go in `.talooner/rules.tln.test`: `test "…" { given { record 1 type "pr"
  attr 1 "pr.lines_changed" 30 … } when rule "…" expect { flagged 1  did 1 approve "pr" } }`.
- Copy the shapes the onboarding draft uses — they compile — and look up anything else
  at https://tln-lang.org/.

## 1. Check the prerequisites

- `docker` is available (`docker version`). If not, stop and tell the user.
- `TALOONER_LICENSE_KEY` is set in the environment. If not, ask the user for it — never
  write it to a file in the repository.
- An LLM is recommended — any OpenAI-compatible endpoint (`TALOONER_MODEL_BASE_URL` +
  `TALOONER_MODEL` + `TALOONER_MODEL_API_KEY`: Qwen, DeepSeek, a local model…), or
  `ANTHROPIC_API_KEY`, or `OPENAI_API_KEY` + `TALOONER_MODEL`. Without one, onboarding writes
  the generic starter ruleset; say so and continue.
- Work from the repository root (`git rev-parse --show-toplevel`). If
  `.talooner/rules.tln` already exists, ask before replacing it.

## 2. Interview the user and write the spec

Ask before you build. If `.talooner/onboarding.md` exists, show it and ask whether to use
it as is. Otherwise look at the repository (folder names, CODEOWNERS, manifests, CI) and ask
the user, one short question at a time:

- **Sensitive paths** — propose the ones you found (auth, permissions, payments,
  migrations, deploy/infra, `.github/workflows`…); the user confirms, drops or adds. For
  each: what it is and **who reviews it** (a team or @user; CODEOWNERS is the default).
- **Extra rules** — PRs need a description, very large PRs are split, new dependencies need
  a security review (when there is a manifest), migrations need a DBA review (when there
  are migrations).
- **AI review** — only if their license includes it: review documented code with AI,
  decision-model triage first where their cluster has a decider? With `CDM_URL` + `CDM_TOKEN` set
  (a context decision model such as Jev or SubQ Snap), onboarding also writes decisions on the PR
  (risk, description quality) — certainty-gated rules (`tool "cdm" "decide"`,
  `result.certainty >= 0.85`); keep them when you tailor the rules.
- **Guides** — only with AI review on: for each sensitive area, is there a doc that says how
  the code there must work (`docs/`, a README, ADRs)? Propose what you found; the user
  confirms, or you write one together in step 3.
- **Anything else** Talooner should know (one line).

Write the answers to `.talooner/onboarding.md` in exactly this shape, show it, and get a yes:

```markdown
# Talooner onboarding spec

## Sensitive paths

Changes here wait for a review before merge.

- `billing/` — payments — reviewed by @acme/payments

## Extra rules

- PRs need a description

## AI review

on

## Guides

- `billing/` — docs/guides/payments.md

## Notes

…
```

## 3. Write the guides the review checks against

Skip this step when AI review is off. With it on, the review is only as good as the guides:
Talooner's AI review reads each changed code unit with the doc linked to it (its diff, its
test diff and the doc from the base branch), so a sharp guide gives sharp findings and a
vague one gives "not sure" on every PR. Section-by-section checks with a decision model are
being built on the same guides — writing them in the shape below works for both. Rules stay
generic; what's specific to this repository lives in the guides.

**Link code to guides** in `.talooner/architecture.yaml`. One entry per folder, not per file;
`kind` is `model`, `controller` or `service`; `doc_ref` is one Markdown file, read from the
base branch:

```yaml
- path: app/services/payments/
  kind: service
  doc_ref: docs/guides/payments.md
```

**Interview per sensitive area** — short questions, one at a time, and write the answers into
that area's guide:

- Which mistakes have hurt you here before? (a double refund, a key in the repo, a float price)
- What must never happen in this code?
- What does the wrong version typically look like? (the line a reviewer would point at)
- Which tests must exist for each file?

Only write rules the user confirmed or an existing doc states. Never invent business rules.

**Shape of a guide** (extend an existing doc rather than starting a second one):

````markdown
# Payments

> One paragraph: what this code does, which files, which docs are elsewhere.

## Money

### Refund cap

A payment can be refunded in parts; the sum of all refunds never exceeds the charge.
Before refunding, add up every earlier refund for the payment.

> **Gotcha**: comparing only the new amount (`amount_cents > payment.amount_cents`) passes
> every single refund but lets two partial refunds add up to more than was paid.

## Security

### Webhooks

Verify the signature with `Stripe::Webhook.construct_event` **before** parsing the payload.

## Specs

### app/services/payments/refund.rb

- **Refund over the cap including earlier refunds**: with an earlier partial refund, a
  second refund that fits the charge alone but not the remainder raises `TooLarge`.
````

- **One rule per `###` section, with a heading that names it.** A decision model answers one
  narrow question sharply; a section that mixes three rules gets an unsure answer.
- **Make every rule checkable.** Name what a reviewer would point at: a call, a check, a
  name, a number. "Code should be clean" is not checkable; "no `rescue => e` that returns
  `nil`" is. When the user gives a vague rule, ask what it looks like in code.
- **Add a gotcha with the typical wrong version** wherever the user has one. It is what turns
  a likely finding into a certain one.
- **A `## Specs` section with `### <file path>` and one bullet per required case.** This is
  how the review finds tests that are missing — or that exist but check something weaker.
- **Style rules too, but only concrete ones:** named constants instead of magic numbers,
  specific error classes, dependencies passed in, no `do_it` / `tmp` names. Judgement calls
  ("single responsibility", "readable") go under an `## Advice` heading: they inform the
  review, they don't block a merge.
- **Ask how serious each area is:** money and security usually hold the merge for the
  owners, style is something the author fixes. Write the answer in the spec's Notes.

**Check the guides against the code before you hand over.** You can read the code: for each
section, does the current code already break it?

- If it does, either the code has a real problem — tell the user, don't fix it silently — or
  the rule is worded wrong; reword it with the user.
- If you can't tell whether the code follows a section, the decision model won't either:
  make the section more concrete, or move it to `## Advice`.
- Start in suggest-only mode: say that blocking on guide findings should wait until the team
  has seen a few weeks of them on real pull requests.

Add the guides and `.talooner/architecture.yaml` to the files you commit in the last step.

## 4. Build the rules from the spec

```sh
docker run --rm -v "$PWD:/repo" --user "$(id -u):$(id -g)" \
  -e TALOONER_LICENSE_KEY \
  -e TALOONER_MODEL_BASE_URL -e TALOONER_MODEL -e TALOONER_MODEL_API_KEY \
  -e ANTHROPIC_API_KEY -e OPENAI_API_KEY \
  -e CDM_URL -e CDM_TOKEN \
  "$IMAGE" onboard
```

No `-it`: you already asked, so onboarding asks nothing — it reads `.talooner/onboarding.md`
by default. Add `--force` only if the user agreed to replace existing rules. It writes
`.talooner/rules.tln`, `.talooner/rules.tln.test` and the CI step
(`.github/workflows/talooner.yml`, or jobs added to `.gitlab-ci.yml`). A non-zero exit means
nothing usable was written: show the error and stop.

## 5. Tailor the rules to this repository

Onboarding only sees the repository's layout. You can read the code, so improve the draft:

- Read `.talooner/rules.tln` and the tests.
- Look at what matters here: auth and permission code, migrations, dependency manifests,
  CI config, infrastructure, secrets handling, public APIs, CODEOWNERS.
- Adjust paths and globs to the real folder names, route sensitive areas to the owners
  in CODEOWNERS, and remove rules that don't apply.
- For every rule you add or change, add or update a case in `.talooner/rules.tln.test`.
- Keep it small: a handful of precise rules beats many vague ones. Plans limit the number
  of rules (Starter 10, Team 20, Pro 50).

## 6. Keep the tests green

```sh
docker run --rm -v "$PWD:/repo" -w /repo --entrypoint tln "$IMAGE" test .talooner/
```

Fix the rules or the tests until every test passes. Never delete a failing test just to
make the suite pass — fix the rule it exposes, or ask the user.

## 7. Hand over

- Summarise each rule in one line for the user, and each guide in one line: which code it
  covers, how many rules and required spec cases it has, and anything the current code
  already breaks.
- Show the CI change onboarding wrote — it tests the rules, then runs the review. Secrets go
  into CI/CD variables or repository secrets, never into the repository.
- If the repository already ran Talooner, onboarding left its CI file alone — then check it
  tests the rules before the review, so a broken policy never reaches a PR: a job that runs
  the step 6 command, with the review job depending on it. On GitHub Actions:

  ```yaml
  jobs:
    rules:
      runs-on: ubuntu-latest
      steps:
        - uses: actions/checkout@v4
        - run: docker run --rm -v "$PWD:/repo" -w /repo --entrypoint tln ghcr.io/talooner/talooner-runner:latest test .talooner/
    review:
      needs: rules
      # … the review step from the snippet
  ```

  On GitLab, the same command in a job of an earlier stage than the review job.
- Ask before committing. With approval, create a branch, commit `.talooner/onboarding.md`,
  `.talooner/rules.tln`, `.talooner/rules.tln.test`, `.talooner/architecture.yaml`, the guides
  and the CI change, and open a pull request.
- No changes of your own to add? `onboard --pr` (instead of step 4's plain `onboard`, with
  `GITLAB_TOKEN` or `GITHUB_TOKEN` passed in) opens the PR/MR itself, CI step included.
