Hangar

Docs · Glidepath

Glidepath: known gaps

Found in use on 2026-09-26/27 while building baggage-api and the values-validation gate. Each has a reproduction or evidence, so they can be picked up later without re-deriving them. Roughly ordered by how much they cost.

# Gap Evidence Direction
1 Image version has no Python support. build-image takes the version from a git tag, then package.json, then pom.xml, else 0.0.0. A Python app is always 0.0.0-<sha>. baggage-api images are 0.0.0-893e163; boarding-api is 1.1.0-8f9acd9. Read pyproject.toml [project] version (yq -p toml works in the toolbox) and a plain VERSION file; add one to the Python scaffold. Also resolve-image-ref only reads the git tag, and its header says it must stay in step with build-image.
2 The onboarding resync can report “up to date” when it is not. For boarding-api it said “gitops repo: .tekton/ already up to date, nothing to deliver” while the gitops repo lacked the new pull-request-values.yaml; a second run delivered it. Likely it compared against a template ConfigMap that had not refreshed yet. onboarding-resync-q8m67 log, 2026-09-27 00:35. Compare the delivered set against the rendered template set by file name and hash, not by the previous run’s state; retry once when the template ConfigMap changed during the run.
3 Deploy paths are hardcoded to platform/envs/<env>.yaml. A standalone Glidepath would write an Airframe-shaped file nothing reads. deploy-manifests, open-release-pr, the PaC exemption, ephemeral-envs, Tower. deploy.releaseFile in cicd.yaml (design in Hangar docs/autopilot/release-file-split.md).
4 An unsigned commit fails the provenance gate on an upper release, and so image-promotion. Agent commits are unsigned. baggage-api release PR #2: commit has no gpgsig. Decision D1 (self-hosted Fulcio for agent commits). Meanwhile a clearer message: which commit, and how to sign.
5 Config-only pushes are not validated. Pushes touching only platform/ or cicd.yaml never build, so a human’s direct edit of an env file on main is checked by nothing. The exemption in deliver-onboarding-files. A push-triggered validate-only flow for env files, or a required PR path for them.
6 Adding a guardrail can hang releases. image-promotion waits for every gate in releaseGuardrails; a repo without the gate’s .tekton file never reports it. wait-for-release-guardrails. Register a gate only after every gitops repo has the file (documented), or have the wait skip gates a repo does not carry.
7 Pull-request pipelines need a preview label and do not run on opened. A PR shows no checks until labelled. baggage-api PR #2 had no checks until the label was added. Say so in the PR comment the platform posts, or run the build on opened when the label is already present.
8 The webhook path is fragile. PaC deliveries reach the dev cluster through a temporary tunnel and a kubectl port-forward; when the forward died, pushes triggered nothing for about 19 hours with no alert. Restarted port-forward 8060:8080 fixed it. A named tunnel, and an alert on “no PaC event in N hours”.
9 A namespace can end up with no PipelineRuns at all, so Tower’s Pipelines tab is empty and nothing explains why. baggage-api, before the U4 test. Keep the last N runs per flow regardless of the pruner, or show “no runs kept” in Tower.
10 Tekton steps run as non-root but scripts assume they can chmod a mount root. validate-values failed with chmod: changing permissions of '/work': Operation not permitted. Fixed 2026-09-27. TaskRun log. Lint Task scripts for chmod/chown on volume roots.
11 The values-validation gate depends on the Airframe image tag. valuesValidatorImage must be moved by hand when the chart pin moves. glidepath-catalog/values.yaml. Derive it from the airframe-application chartVersion already pinned in glidepath-app.
12 open-release-pr writes releaseTracking.relayHostAliasIP from the dev node’s status.hostIP, an address a second cluster cannot route to; the outcome hooks then time out and a new Flight env’s first sync fails. baggage-api-staging, 2026-09-27; same as the parked bug in the Skyport handoff. Also listed in Airframe’s known gaps. Per-cluster relayHostAliasIP in the cluster registry, hostIP as fallback.
13 The values-validation gate hit three Tekton-script bugs on its first real runs (chmod on the mount root; workingDir on a read-only mount; an unpublished validator image tag). All fixed 2026-09-27. TaskRun logs. Run a new Task once against a real PR before relying on it; add a fixture-driven test for Task scripts.
14 Documented 2026-09-27 (see github-ruleset.md); the problems it found are open. Was: the GitHub ruleset that enforces every guardrail was not documented. It is the thing that makes the checks required, so it is a mandatory install item, yet the docs describe classic branch protection “not IaC-managed” and say nothing of rulesets: scope, required check names (Pipelines as Code CI / <gate>-), bypass actors, which repos. releaseGuardrails and the ruleset’s required list must be kept in sync by hand; a mismatch either never blocks or blocks forever. The GitHub API refuses to show rulesets and branch protection for these private repos to a plain token (“Upgrade to GitHub Pro or make this repository public”), so an export is needed to audit it. docs/admin/release-guardrails.md “Branch protection”; gh api repos/.../rulesets returns 403 on the free plan. Export the ruleset JSON, audit it, document it, and make applying it an install step (ideally generated from releaseGuardrails, e.g. a RepositoryRuleset from the same list). Note the plan question: rulesets on private repos need a paid plan.
15 The required checks assume every PR is a release PR. All gates run only on release-* heads, so onboarding-resync, Tower Config, hand-edit and seed PRs would never satisfy the ruleset’s required checks. Audit of the exported ruleset against every gate’s on-cel-expression. Run every gate on every PR and pass immediately for non-release PRs, or add an admin bypass.
16 Bots write directly to the gitops default branch (the composition’s RepositoryFiles), which a pull-request rule would refuse. values-yaml.yaml in the ApplicationEnvironment composition. Make the writing GitHub App a bypass actor (--bypass-app-id).