Docs · Autopilot
Autopilot: user guide
For people who define and run agents. Autopilot runs on hangar-dev (the gateway image gateway-v0.4.0 calling
clearance v0.29.0’s core, as of 2026-11-03); Hangar’s portal on hangar-prod shows it (the Autopilot and Clearance pages,
and Tower’s Agent tab per app). Hangar’s docs/autopilot/roadmap.md has the
plan.
Today
-
Write an agent definition in
agents/(schema:schemas/). It names the agent’s tier, the repos and paths it may touch, and its budgets. Baseline deny paths (.tekton/**,CODEOWNERS,.github/**, appproject files, release files) apply to every agent and cannot be removed. -
cicd.yaml is scoped by field, not denied whole. An agent may change a
cicd.yamlin a pull request, but only within Glidepath’s contract: fields markedopenfreely,tightenfields (sast, imageScan, policyCheck, sbom, githubMerge, a step’srequired) only the strict way, and never ahumanfield (secrets, allowedCommitSigners, deploy target, clusters, gitops repos), a Flight environment, a check-ride step or a required test step. Clearance runs Glidepath’s own check (clearance’spacks/hangar/vendor/cicd_scope.py, vendored byte for byte) on the file’sbeforeand new content and denies with the Glidepath rule id (GP-SCOPE-001human field,GP-SCOPE-002gate loosened,GP-SCOPE-003Flight environment or tier) and its hint; every problem is listed underproblems. Send the file’s current content asbefore: without it the file counts as new, and a new cicd.yaml is a human’s change.op: merge-patchcontent is applied tobeforefirst. The generated.tekton/stays denied whole. -
Score it with Preflight. Cases in
preflight/cases/run deterministically against a definition; a case must be able to fail, and the harness checks that it can:autopilot preflight run --case <id>scores a scripted good run,--seeded-badthe run the case exists to catch (docs/admin/preflight.md). -
Plan an application from one statement. The AppSpec planner (
src/autopilot/airframe_plan.py, example inexamples/parachute.appspec.yaml) produces the ordered change set that creates an app, its environments and their configuration, without touching a repo. -
Ask Airframe through Clearance. An agent with the
airframe.*tools (agents/airframe-operator.yaml) can read what Airframe offers (airframe.capabilities), check env-file or values content before proposing it (airframe.validate, airframe’s own validator: AF-* rule ids, JSON pointers, hints; not in Hangar’s gateway image, so no bundled agent holds it), look up a rule or a condition reason (airframe.explain), plan an AppSpec (airframe.plan: pass the app’s current cicd.yaml asbaseCicd), and read an app’s XR conditions, an environment’s Argo CD Application and Rollout, and an XR’s verify checks (airframe.status,airframe.describe,airframe.verify). Those three read the cluster and are limited to the apps underprofile.airframe.apps(none listed means none).verifynever reads a Secret or opens a port-forward: those checks come backskippedwith the reason. A Flight environment’s Application and Rollout run on its own cluster;describesays so. -
Stand an app up from one statement.
agents/parachute.yamlrunsairframe.applyon an AppSpec (examples/parachute.appspec.yaml): it opens the plan’s first pull request (the tenants repo: the app and its Flight environments), and you merge it. Run it again with the same AppSpec and it opens the next (the app’s repo: its Ground environments and cicd.yaml) once the platform has created the repo; each call opens one, or tells you which is waiting on you. It never merges, and it never opens the Flight half (the Flight fields of cicd.yaml,gitops-<app>): those come back ashumanStepsfor you. If a run is interrupted, run it again: it picks up from GitHub and opens no duplicate. A spec the chart rejects (examples/parachute-bad.appspec.yaml) opens nothing and says which field. -
Propose a release through Glidepath. An agent with
glidepath.promoteorglidepath.rollback(agents/release-proposer.yaml) proposes a promotion to the next Flight environment, or a rollback to one of the environment’s rollback-plan targets: glidepath-api starts the app’s release run, which opens the gitops PR, and a person merges it. Read the plan first (glidepath.environments.list,glidepath.environments.rollbackPlan), passdryRun: trueto check everything without starting anything, and follow the release withglidepath.releases.get. Retrying the same call starts no second run. A refusal (out of order, a Ground target, a target not in the plan) comes back as a denial with Glidepath’s rule (GP-API-422) and hint. The definition lists no tool that reaches GitHub, so the merge is always a person’s.tools/glidepath_release_smoke.pyruns it against a live glidepath-api (dry run unless--propose). -
Change an app’s
cicd.yamlthrough Glidepath.glidepath.cicd.validate(T0) takes a JSON merge patch and asks glidepath-api what it would mean: valid or not, each finding with itsGP-*rule and fix, every field the change touches with its scope (open,tighten,human), and the resulting file.glidepath.cicd.propose(T1,agents/coding-agent.yaml) asks the same and, when the change is clean, opens the pull request: one commit ofcicd.yamlon the app’s own repo (repo: owner/<app>), as the agents’ App, with the verdict and the changed fields in the PR body; a person merges it. A change an agent may not make (ahumanfield, a gate turned off, a Flight environment) is refused with the sameGP-SCOPErule the PR’scicd-validatecheck would post, before anything exists on GitHub. The PR counts againstopenPrsand carries the agent gates’ receipt likerepo.pr.open. Arepo.pr.openwhose files include the app’s rootcicd.yaml(a code change with its pipeline step, say) gets the same verdict first, so nocicd.yamlreaches GitHub through Clearance without it; R021 still runs on everycicd.yaml, at any depth. -
Run an agent. From the portal’s Autopilot pages, a person’s Run starts an in-cluster agent as an
AgentRunwith your input as its prompt and the definition’sruntime.instructionsbeside it; its session has the definition’s budgets, and a child run’s budget comes out of its parent’s. A run hands back its answer as it ends (run_finish), kept 30 days on the run’s page. Agents can also start on a schedule (triggersinterval) or on a Glidepath event. -
Keep a definition in your app’s repo. An
AgentXR (airframexrds/agent.yaml) pins one commit of a definition file in the app’s own repository; the gateway loads it beside the bundledagents/(Autopilot M4). Its release is reviewed through the deployment gate (Clearancereview.py). -
Answer an agent.
human.requestquestions arrive in the portal; the session’s owner or the definition’sownergroup answers. Freeze or end a session, and hold or release an agent’s triggers, from the same pages. -
Use your own MCP client. Sign in through people-dex (
tools/hangar_login.py, the README’s “Signing in as a person”) and call Clearance’s tools as yourself; Clearance enforces the definition’s envelope, but your client is the agent. When you are done,session_closeends your session at once (it is recorded, and any runs it spawned are deleted) instead of leaving it open until its TTL; only you can close your own session this way.
Not yet
Tools without a backend on Hangar (chat.*, airframe.validate; no definition names them), xr.request and airframe.apply waiting on
Glidepath’s broker to allow the tenants repo (airframe.apply leaves the Flight half to people), app.api.get with no services configured, and the Skyport agents that
need them; the README’s “What is NOT built” has the full list.
Run the tests: ./.venv/bin/python -m pytest -q (no cluster needed).