Whether you get a second chance
Risk says how bad a change is. It never says whether you can take it back, and the two come apart constantly: restarting a fleet is high risk and undoes itself, while deleting a backup set reads quietly and is permanent. Every run is graded reversible, costly, or irreversible, on every tier. A rule that holds a run on that grade is a reversibility floor, which is Pro. An Ansible run is graded from what it actually runs, every role and include read from the project at the commit that executes, not guessed from a file name.
Your estate as it was
One gather per host per day is kept rather than overwritten, about four hundred days deep by default, so you can ask what was running on the date of your last audit, and what has moved since: host by host, fact by fact, with the value at each end. Most tools answer only what is true now, because reconstructing the past needs an ordered history nobody can quietly edit.
The change, not just the run
Nobody means a run. They mean "we rolled out the fix", which was four runs, a rollback and a fix-forward, across three days. Label them and read the whole arc as one thing, with its span, everyone who acted, and an outcome worked out from the runs rather than typed in by whoever closed it. Make the label a ServiceNow change number or a Jira issue key, and the official plugin, a separate binary, records each run on that ticket.
Balanced splits
Shard a big job across hosts, balanced by each host's measured duration. Retry only the shards that failed, not the whole run.
Fleet memory
It flags flaky hosts, trends how long each task takes, and keeps every host's history across runs. Most controllers keep each run's history but never flag a flaky host or trend a task's duration.
Visual workflow editor
Drag steps from all seven tools into one graph. Fan out, fan in, retry any step, run the whole pipeline. No YAML by hand.
Schedules you can trust before you save
Type a cron expression, or an RFC 5545 recurrence rule for what cron cannot say, such as the last Friday of each quarter, and see its next firings before you save it. A scheduled launch carries its template's approvals, notifications, and timeout, and every run records which schedule started it. A server that stops mid-fire hands the occurrence back, and the occurrence's key keeps it from running twice. Where several servers share a PostgreSQL database, another takes it up.
Roles, teams, and orgs
Global roles, teams, organizations, and per-object read, use, and manage grants. Delegate view of one credential without a global viewer, or a whole org inherits a project at once. All of it ships in the core, not a paid tier.
Optional advisory AI
Off by default. Switch it on to triage a failure, answer a fleet question, or draft a run from a sentence. It proposes, never executes. Bring your own model: local Ollama, Claude, or any OpenAI-compatible API.
A doctor for your control plane
One click verifies every registered reference: templates to inventories, projects, and credentials, schedules to templates, every cron expression. Broken links surface with a fix button before they break a run.
Run it again, your way
Rerun any finished run with its exact spec, credentials included, one click. Or launch a template with overrides: host limit, inventory, credential picks, extra vars, dry run. Every override is authorized like a fresh launch.
Built for audits and sharing
Every list exports to CSV or JSON, filtered exactly as you see it. Every run exports its events, log, and per-host results. Copy a link to any run, in any of the three themes.
Every run knows where it came from
Each run records what fired it, the template, schedule, rerun, or drift fix behind it, and who asked. Add labels like env=prod, then search with fielded terms: status:failed host:web01 label:env=prod, resolved across your whole history.
Notifications everywhere
A finished run, or one held for approval, reaches Slack, Teams, Discord, Mattermost, Rocket.Chat, ntfy, email, or a webhook. A failure pages PagerDuty or texts through Twilio, and every run lands on your Grafana dashboards as an annotation. Eleven channels, server-wide or per template, so each team pages its own people. A named target's deliveries are queued in the database in the same write as the event, sent in the run's order, retried, and made by the next server to start if one stops.
Secrets kept out of the log
Sealed at rest, sourced live from Vault, AWS, Google, Azure, CyberArk, or 1Password, and kept off the command line so nothing shows in the process table. A tool that prints a secret shows ***, even when it re-encodes it as base64, hex, or an escaped string. Typed cloud credentials inject the exact variables each tool expects.
Inventories read the way Ansible reads them
Static INI, YAML, and JSON inventories, and the smart inventories filtered over them, resolve inside the binary with Ansible's own quirks, from value typing to host ranges, so the server needs no Ansible to read them. CI holds that reading to every ansible-core minor from 2.16 to 2.21, and before an Ansible run the executor's own ansible-inventory reads the same inputs, so any difference refuses the run.
Hosts that configure themselves
A new machine posts the template's callback key to its callback URL at boot, and the template runs against that host alone. It is AWX's provisioning callback, matched to the caller by AWX's rules and gated like any launch. A template imported from AWX answers at its old AWX address too, when the import knows its AWX id, so boot scripts keep working once the hostname points here.
Cloud access with nothing stored
A federated credential holds no secret. Each run that uses one gets a short-lived identity token, signed here and naming the run, its project, template, environment, and who launched it, which AWS, Google Cloud, or Azure exchanges for credentials that expire on their own. The signing key rotates on a fixed schedule that gives each cloud a day to fetch the new key, or at once in an emergency.
Policies in Rego
Write approval policy in the Open Policy Agent language, so an OPA or Conftest rule you already have ports without a rewrite. Evaluation never leaves the process: network, clock, and random builtins are removed, so a run gets the same answer on every server, and the decision records the digest of the exact bundle. Rego policies are Team.
A dry run has to be dry
A rule that lets dry runs through first reads each one for the known ways a check or a plan acts: tasks that set check_mode: false, pipe lookups that run a command on the controller, and the external, aws_lambda_invocation, and writing http data sources a plan would call, in the configuration and every module it calls. A dry run that could act for real is held like the real run, with a note naming what was found. The scan cannot prove a preview harmless, since lookups, plugins, and providers run code too, so the rule trusts the code it lets through, and an agent's dry run waits for a person either way, unless an exemption covers it.
Plans on pull requests
A review trigger plans a GitHub or GitLab pull request at its head commit in the tool's no-change mode and posts the result on the pull request as one comment per template, updated in place on every push, with a commit status beside it. A person whose GitHub or GitLab account is linked can comment /switchtender apply to approve and apply the reported plan, with the same role, grants, and separation of duties as the approval queue. How it works.