Refine AGENTS guidance for Ansible validation workflows

This commit is contained in:
Fabio Scotto di Santolo
2026-03-17 22:43:36 +01:00
parent 9b61ee63cf
commit 6c0cbccfcd

129
AGENTS.md
View File

@@ -19,40 +19,33 @@ Current `ansible.cfg` defaults:
- `retry_files_enabled = False` - `retry_files_enabled = False`
## Local instruction files (Cursor/Copilot) ## Local instruction files (Cursor/Copilot)
As of now, these files are not present: Checked in this repository:
- `.cursorrules` - `.cursorrules`: not present
- `.cursor/rules/` - `.cursor/rules/`: not present
- `.github/copilot-instructions.md` - `.github/copilot-instructions.md`: not present
If any appear later, treat them as higher-priority local instructions. If any of the files above appear later, treat them as higher-priority local instructions.
## Build, lint, and test commands ## Build, lint, and test commands
There is no compile/build artifact in this repo. There is no compile/build step in this repo.
Validation is performed with syntax checks, dry-runs, inventory checks, and linting. Validation is Ansible syntax checks, dry-runs, inventory checks, and linting.
Main apply run: Core apply run:
```bash ```bash
ansible-playbook ansible/site.yml ansible-playbook ansible/site.yml
``` ```
Dry-run with diff: Safe dry-run with changes preview:
```bash ```bash
ansible-playbook ansible/site.yml --check --diff ansible-playbook ansible/site.yml --check --diff
``` ```
Run one host: Target a single host (useful for SSH-first rollout):
```bash ```bash
ansible-playbook ansible/site.yml --limit ikaros ansible-playbook ansible/site.yml --limit ikaros
``` ```
Inventory sanity checks: Linting (if installed locally):
```bash
ansible-inventory --graph
ansible-inventory --list
ansible all --list-hosts
```
Linting (if installed):
```bash ```bash
ansible-lint ansible/site.yml ansible-lint ansible/site.yml
ansible-lint ansible/roles ansible-lint ansible/roles
@@ -60,52 +53,51 @@ yamllint ansible/
``` ```
## Single-test equivalents (important) ## Single-test equivalents (important)
There is no Molecule/pytest test suite in this repo. There is no Molecule/pytest suite.
Use these targeted checks as "single test" workflows. Use one of these as a "single test" workflow.
Syntax-only check: Fast syntax-only validation:
```bash ```bash
ansible-playbook ansible/site.yml --syntax-check ansible-playbook ansible/site.yml --syntax-check
``` ```
Best single-host safety test: Best default single-host safety check:
```bash ```bash
ansible-playbook ansible/site.yml --limit nymph --check --diff ansible-playbook ansible/site.yml --limit nymph --check --diff
``` ```
Start from one known task: Single-role smoke test using `--start-at-task` (dotfiles path):
```bash ```bash
ansible-playbook ansible/site.yml --limit ikaros --start-at-task "Copy common dotfiles" --check --diff ansible-playbook ansible/site.yml --limit ikaros --start-at-task "Copy common dotfiles" --check --diff
``` ```
Role-boundary approximation: Single-role smoke test using `--start-at-task` (Void packages path):
```bash ```bash
ansible-playbook ansible/site.yml --limit ikaros --start-at-task "Install Void nonfree repository if needed" --check --diff ansible-playbook ansible/site.yml --limit ikaros --start-at-task "Install Void nonfree repository if needed" --check --diff
``` ```
Notes: Notes:
- Current active stack in `site.yml`: `dotfiles_common`, `packages_void`, `services_runit`, `profile_desktop_i3`. - Current active stack in `ansible/site.yml`: `dotfiles_common`, `packages_void`, `services_runit`, `profile_desktop_i3`.
- Use `--tags` for targeted runs when tags are available. - Ubuntu/systemd/workstation/server roles exist in the repo but are not currently included by `ansible/site.yml`.
- Minimum dependencies: Python 3, Ansible, host access (local or SSH). - Minimum dependencies: Python 3, Ansible, target host access (local or SSH). Setup: `python3 -m pip install ansible`.
- Setup example: `python3 -m pip install ansible`.
## Code style guidelines ## Code style guidelines
### Core principles ### Core principles
- Prefer idempotent, declarative, host-safe automation. - Prefer declarative, idempotent, host-safe automation.
- Preserve layering: `all -> OS -> profile -> host`. - Keep layering explicit: `all -> OS -> profile -> host`.
- Keep edits minimal and scoped to user intent. - Keep changes minimal, scoped, and reversible.
- Avoid speculative refactors unrelated to the requested change. - Avoid speculative refactors unrelated to the requested task.
- Optimize for readability over clever Jinja/YAML compression.
### Modules, imports, and task structure ### Modules, imports, and task structure
- Use FQCN modules (`ansible.builtin.copy`, `community.general.xbps`). - Use FQCN modules (`ansible.builtin.copy`, `community.general.xbps`).
- Prefer modules over `ansible.builtin.command`/`ansible.builtin.shell`. - Prefer dedicated modules over `ansible.builtin.command` and `ansible.builtin.shell`.
- Use `command`/`shell` only when no module fits; explain intent in task name. - Use `command`/`shell` only when no module exists; explain intent in task name.
- When using `command`/`shell`, set `changed_when` and `failed_when` as needed. - For `command`/`shell`, define `changed_when` and `failed_when` when defaults are unsafe.
- Keep `ansible/site.yml` orchestration-only; implementation belongs in roles. - Keep `ansible/site.yml` orchestration-only; place implementation details in roles.
- Keep roles focused by domain (packages, services, profile, dotfiles). - Keep roles domain-focused (packages, services, profiles, dotfiles).
- Split large task files with `import_tasks`/`include_tasks`.
### YAML formatting and file hygiene ### YAML formatting and file hygiene
- Start YAML documents with `---`. - Start YAML documents with `---`.
@@ -113,54 +105,47 @@ Notes:
- Keep key ordering stable and meaningful. - Keep key ordering stable and meaningful.
- Quote file modes as strings (`"0644"`, `"0755"`, `"0600"`, `"0700"`). - Quote file modes as strings (`"0644"`, `"0755"`, `"0600"`, `"0700"`).
- Use multiline Jinja for long expressions. - Use multiline Jinja for long expressions.
- Avoid trailing whitespace and noisy reformatting. - Avoid trailing whitespace and formatting-only churn.
### Variables, types, and templating ### Variables, types, and templating
- Use `snake_case` variables. - Use `snake_case` names for variables.
- Use semantically scoped names (`common_packages`, `void_packages_base`, `host_packages`). - Use semantically scoped names (`common_packages`, `void_packages_base`, `profile_packages`, `host_packages`).
- Keep booleans as real booleans (`true`/`false`), not quoted strings. - Keep booleans as booleans (`true`/`false`), not quoted strings.
- Keep lists/maps as YAML collections, not comma-separated strings. - Keep lists/maps as YAML collections, not comma-separated strings.
- Use guards for optional values: `default([])`, `default({})`. - Guard optional values with `default([])` and `default({})`.
- Build home-relative paths from `{{ user_home }}` consistently. - Build home-relative paths from `{{ user_home }}` consistently.
- Put shared defaults in `group_vars/all.yml`; specialize in group/host vars.
### Naming conventions ### Naming conventions
- Role directory names: lowercase with underscores. - Role directory names: lowercase with underscores.
- Task names: imperative and outcome-based. - Task names: imperative, outcome-based, and unique enough for `--start-at-task`.
- Keep inventory group names and var file names aligned. - Keep inventory group names aligned with related var files.
- Host var filenames must match hostnames exactly.
### Error handling and safety ### Error handling and safety
- Guard OS/profile-specific behavior with `when`. - Guard OS/profile-specific behavior with `when` clauses.
- Prefer explicit `loop` inputs; avoid implicit assumptions. - Prefer explicit loop inputs over implicit assumptions.
- Do not suppress failures without a clear operational reason. - Do not suppress failures unless there is a clear operational reason.
- Validate risky changes with `--check --diff` before full apply. - Validate risky changes with `--check --diff` before full apply.
- Avoid destructive operations in user homes unless explicitly required. - Avoid destructive operations in user homes unless explicitly required.
- Never commit credentials or contents from `secrets/`. - Keep tasks non-interactive and automation-safe.
### Dotfiles and shell script style ### Dotfiles and shell script style
- Prefer POSIX `sh`; use Bash only when required. - Prefer POSIX `sh`; use Bash only when Bash features are required.
- Bash scripts should use `#!/usr/bin/env bash`. - Bash scripts must use `#!/usr/bin/env bash`.
- Quote expansions (`"$var"`) unless intentional splitting is required. - Quote expansions (`"$var"`) unless intentional word splitting is required.
- Keep scripts non-interactive when run by automation. - Preserve executable bits for copied scripts (`mode: preserve` where appropriate).
- Preserve executable bits on scripts copied with `mode: preserve`.
## Agent workflow expectations ## Agent workflow expectations
- Do not modify unrelated files. - Do not modify unrelated files.
- Verify assumptions by reading inventory, vars, and active roles before editing. - Read inventory, vars, and relevant roles before editing.
- Keep AGENTS and README aligned when workflow or commands change. - Keep AGENTS and README aligned when workflows/commands change.
- When adding new domains/roles, also add tagging and validation guidance. - When adding roles or domains, also add validation and targeting guidance.
- Prefer `--limit <host>` validation before broader runs.
## Pre-merge checklist ## Pre-merge checklist
Run before proposing or finalizing changes: Run before proposing/finalizing changes:
```bash - `ansible-playbook ansible/site.yml --syntax-check`
ansible-playbook ansible/site.yml --syntax-check - `ansible-playbook ansible/site.yml --check --diff --limit <host>`
ansible-playbook ansible/site.yml --check --diff --limit <host> - `ansible-inventory --graph`
ansible-inventory --graph - If available: `ansible-lint ansible/site.yml` and `yamllint ansible/`
```
If lint tooling is installed:
```bash
ansible-lint ansible/site.yml
yamllint ansible/
```