Skip to content

Automation

Archi edited this page Oct 20, 2026 · 2 revisions

Automation

Nautelle can start agent work without anyone at a keyboard: run a skill on a project, fire it on a schedule, trigger it from an outside system with an inbound webhook, push Nautelle's own events out with outbound webhooks, and learn about GitHub changes instantly through a GitHub App. Every automated start sends the same typed runner command a person would, so it shows up as an ordinary run in history, priced and subject to budgets.

flowchart LR
  person["Person: Run"] --> cmd
  sched["Schedule<br/>(cron, BullMQ timer)"] --> gate
  hook["Inbound webhook<br/>POST /hooks/&lt;id&gt;"] --> gate
  gate{"Budget gate"} --> cmd["Typed runner command<br/>skill.run · orchestrator.start"]
  cmd --> runner["Runner: own worktree<br/>+ tmux session"]
  runner --> out["Report or pull request"]
  events["Nautelle events"] --> outhook["Outbound webhooks<br/>signed, retried"]
  gh["GitHub App"] -->|"poll now"| runner
Loading

Skills

A skill is a packaged agent workflow (SKILL.md). Nautelle lets you find, install and run skills per project.

Find and install

  1. Open Skills (/skills) and search the public skills.sh catalog.
  2. Pick a skill. The runner shallow-clones its GitHub repository, pins the commit and shows a preview.
  3. Install it:
    • into a project — the runner opens a pull request on branch skills/<name> that copies the skill into .claude/skills/<name>/;
    • into a runtime profile (admin) — it is copied into the profile's skills directory and every session on that profile loads it. This also needs skills.profileInstall allowed in the runner's local policy.

Skills are copied, never installed with npx or symlinked, and each copy records its source, commit and content hash. Project › Skills lists every skill available to the project: installed from the catalog, written by hand, from profiles or from plugins.

Run

  1. Open Project › Skills, choose a skill and Run.
  2. Choose the runtime profile, the model, arguments and the output:
    • Report — the agent's final message, the changed files and the diff;
    • Pull request — the changes are committed and a PR is opened against the project's base branch.
  3. Watch the live log on the run page (/projects/<id>/skills/runs/<runId>). An admin can attach to its terminal.

Each run gets its own worktree and tmux session, so it never touches your checkout. Defaults: 60-minute timeout (6 hours maximum) and 2 concurrent runs per runner — more wait in a queue. The orchestrator and worker skills themselves cannot be run this way.

Schedules

A schedule runs a skill or an orchestrator command on a project at fixed times — a security scan every night, orchestrator next every hour.

  1. Open Project › Schedules (or Admin › Schedules across projects).
  2. Choose the target: a skill (with profile, model and output) or the orchestrator (start or next).
  3. Enter a 5-field cron expression and a time zone.
  4. Choose the missed-run policy.
Policy When the API or runner was down
skip (default) records the missed occurrence as skipped and waits for the next one
catch_up fires once for the newest missed occurrence; older ones are recorded as skipped. Nothing older than 24 hours is caught up

Rules that keep schedules safe:

  • The minimum interval between firings is 5 minutes.
  • A schedule never has two live runs: if the previous run is still going, the new occurrence is skipped.
  • It fires with its creator's authority at fire time. If the creator is no longer an operator of the project, the schedule is disabled.
  • Five consecutive failures disable it.
  • Budgets are checked before every firing.
  • Run now fires one occurrence immediately without moving the next run.

Schedules are stored in PostgreSQL; BullMQ on Redis provides the timers. Redis holds nothing that cannot be rebuilt from the database. The admin page also lists the API's own system jobs read-only.

Webhooks

Admins manage webhooks under Admin › Integrations.

Inbound triggers

Integrations › Triggers creates a URL that starts work when an outside system calls it — a CI failure starts a debugging skill, a deploy starts a UX test.

  • POST /hooks/<triggerId>, JSON only, signed:

    X-Nautelle-Timestamp: <unix seconds>
    X-Nautelle-Delivery:  <unique id>
    X-Nautelle-Signature: sha256=HMAC-SHA256(secret, "<timestamp>.<delivery>.<raw body>")
    
  • The action is a skill run or orchestrator next on one project. Skill arguments may use {{payload.<path>}} placeholders, limited to the paths you allow.

  • Limits: 30 accepted deliveries per trigger per hour, one live run per trigger, timestamps within ±5 minutes, replayed delivery ids refused.

  • The caller gets 202 at once and never waits for the agent. Unknown triggers answer 404.

Outbound webhooks

Integrations › Webhooks sends Nautelle events — orchestrator, slots, pull requests, a person needed, budget alerts and more — to a URL you choose (n8n, Slack, your own bot).

  • Each delivery is signed: X-Nautelle-Signature: t=<unix>,v1=HMAC-SHA256(secret, "<t>.<body>"), with X-Nautelle-Event and X-Nautelle-Delivery.
  • Payloads are a fixed envelope built from an allowlist of fields, never raw events.
  • Failed deliveries retry with exponential backoff, up to 8 attempts. After 10 consecutive failures the webhook's circuit opens for 15 minutes.
  • A delivery log shows each attempt; you can redeliver or send a test.
  • Only https:// targets are allowed unless an admin allowlists the host, and private, loopback and link-local addresses are refused at send time.

GitHub App

Without an App, each runner polls its projects' issues and pull requests every 60 seconds. A GitHub App pushes the same facts the moment they happen, and Nautelle turns each delivery into an immediate poll on the right runner.

  1. Set APP_ENCRYPTION_KEY (and PUBLIC_URL, so GitHub can reach the server) in the API environment — see Self-Hosting.
  2. Open Admin › Integrations › GitHub and choose Create GitHub App. GitHub's manifest flow creates a read-only App (issues, pull requests, checks, statuses, contents).
  3. Install it on your repositories. Installations map to projects by repository.

GitHub must reach <PUBLIC_URL>/hooks/github over HTTPS — a public reverse proxy, Tailscale Funnel or a Cloudflare Tunnel. While the App is healthy for a project, polling relaxes to every 10 minutes; if GitHub cannot reach you, nothing breaks and polling stays at 60 seconds. Each project's settings show whether it is covered and healthy. The App only reads; every write to GitHub still goes through the runner's gh.

See also

Decisions: ADR-0004 · ADR-0007 · ADR-0015 · Spec: #24, #25, #26, #27, #123

Clone this wiki locally