01 · A different kind of repo
No HelmReleases, no Kustomizations. Just roles.
An Ansible repository looks nothing like a Flux repository (the git repository that a Kubernetes cluster follows). The Kubernetes-shaped agents parse nothing in it. So the failure mode is not a wrong proposal. It is silent zero coverage: the assistant scans the repository, finds nothing and says nothing.
Treating Ansible repositories as first-class targets starts with admitting this. The next step is to build lanes that understand them.
02 · What CI already does
Lint and plan on every MR. Apply every hour.
In a typical setup, a merge request runs syntax-check,
ansible-lint and a --check --diff plan. The main branch applies on push and on a schedule. The scheduled apply is the reconciler of this repository, the Ansible equivalent of Flux.
The MR gate is good at what it checks. But by its structure, it cannot report that its own reconciler has died.
03 · Watch the reconciler In development
OK, stale, red, or unknown. Never "probably fine".
A rule-based run-health check reads the scheduled runs and gives one of four verdicts. Stale: no scheduled run in two
cadences. Red: the last K scheduled applies all failed.
Unknown: no token, an API error or incomplete pages. Unknown never reads as OK.
We tune the thresholds by replaying the full run history, not by waiting a week. The check only reports. Opening an issue from its verdict is on the roadmap.
04 · Read the run log In development
A PLAY RECAP is structured data.
A parser turns an ansible-playbook job log into facts: plays, tasks, per-host results and the recap. In
--check mode, changed>0 is a genuine drift signal. It means the live hosts differ from the repository.
The parser is honest about its limit. A run log cannot prove that a named resource exists, so the parser answers "can't tell", never "absent". The parser is built. No production lane uses it yet.
05 · CI hygiene Roadmap
The plan on this MR belongs to a different MR.
The plan step writes to a fixed /tmp/plan.txt on a
self-hosted runner whose /tmp survives between jobs.
The publish step runs if: always(). When this MR's
plan never ran, reviewers see yesterday's plan from someone else's
change.
That misleads reviewers and discloses diffs across merge requests. A rule can detect this from the workflow file alone.
06 · CI hygiene Roadmap
Green every hour, doing nothing every hour.
A guard step finds that a required secret is missing. It sets
ready=false and lets the job finish green, "rather
than failing hourly". Every scheduled apply becomes a successful no-op. A run-health check that only reads the status says OK.
The planned rule flags the pattern. The fix is to fail loudly on scheduled
runs, or to read step outcomes and demote a skipped run to unknown.
07 · Role pins Roadmap
Versions live in role defaults, not in requirements.yml.
In practice the pins that matter sit in
roles/*/defaults/main.yml (*_version,
*_ref, image digests) and in the CI image's build
arguments. A rule-based lane will read them and look up upstream releases. Then it will propose the same evidence-based target that the Kubernetes upgrade lane uses.
08 · Failure triage Roadmap
When the playbook is the victim, not the cause.
The assistant will compare the log tail of a failed job with known signatures. Examples are a sealed Vault, a registry pull error and DNS. When the repository declares the dependency, the assistant will attribute the failure to the repository that owns it. The proposal then lands there. The
cross-domain story follows one such
failure all the way to a missing probe.
09 · The proposal
A small workflow fix, with the reason spelled out.
The fix changes three lines. Two move the plan to a per-run path, and one guards the publish
step. The MR explains the mechanism and shows the evidence from the repository's own history. It also warns that the MR itself triggers the check job on the fleet. The full MR is below.