diff --git a/AGENTS.md b/AGENTS.md index 3d0feaa..3fb9799 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,16 +1,16 @@ # AGENTS.md -Agent guide for this repository. -Project type: Ansible infrastructure with managed dotfiles. +Guidance for coding agents working in this repository. +Project type: Ansible infrastructure + managed dotfiles. -## Scope and layout +## Repository scope and layout - Entry playbook: `ansible/site.yml` - Inventory: `ansible/inventory/hosts.yml` - Group vars: `ansible/inventory/group_vars/*.yml` - Host vars: `ansible/inventory/host_vars/*.yml` - Roles: `ansible/roles/*/tasks/main.yml` -- Dotfiles source: `dotfiles/` -- Ansible config: `ansible.cfg` +- Dotfiles source of truth: `dotfiles/` +- Ansible config file: `ansible.cfg` Current `ansible.cfg` defaults: - `inventory = ansible/inventory/hosts.yml` @@ -18,17 +18,17 @@ Current `ansible.cfg` defaults: - `host_key_checking = False` - `retry_files_enabled = False` -## Cursor and Copilot instructions -Checked in this repo and not found: +## Local instruction files (Cursor/Copilot) +As of now, these files are not present: - `.cursorrules` - `.cursor/rules/` - `.github/copilot-instructions.md` -If any of these are added later, treat them as higher-priority local instructions. +If any appear later, treat them as higher-priority local instructions. ## Build, lint, and test commands There is no compile/build artifact in this repo. -Validation is done with syntax checks, dry-runs, inventory checks, and linting. +Validation is performed with syntax checks, dry-runs, inventory checks, and linting. Main apply run: ```bash @@ -49,6 +49,7 @@ Inventory sanity checks: ```bash ansible-inventory --graph ansible-inventory --list +ansible all --list-hosts ``` Linting (if installed): @@ -59,102 +60,99 @@ yamllint ansible/ ``` ## Single-test equivalents (important) -There is no dedicated test harness (no Molecule/pytest suite). -Use these as targeted single-test workflows: +There is no Molecule/pytest test suite in this repo. +Use these targeted checks as "single test" workflows. -Syntax-check only: +Syntax-only check: ```bash ansible-playbook ansible/site.yml --syntax-check ``` -Dry-run one host (best single test): +Best single-host safety test: ```bash ansible-playbook ansible/site.yml --limit nymph --check --diff ``` -Start from one known task name: +Start from one known task: ```bash -ansible-playbook ansible/site.yml --limit ikaros --start-at-task "Copy .bashrc" --check --diff +ansible-playbook ansible/site.yml --limit ikaros --start-at-task "Copy common dotfiles" --check --diff ``` -Run one role by task boundary (practical approximation): +Role-boundary approximation: ```bash ansible-playbook ansible/site.yml --limit ikaros --start-at-task "Install Void nonfree repository if needed" --check --diff ``` -List hosts targeted by current inventory: -```bash -ansible all --list-hosts -``` - Notes: -- `--tags` is preferred for targeted runs once tasks are tagged consistently. -- Today, `site.yml` actively applies `dotfiles_common`, `packages_void`, `services_runit`, and `profile_desktop_i3`. -- Dependencies: Python 3, Ansible, and host access (local or SSH depending on inventory). -- Setup: `python3 -m pip install ansible` (plus optional `ansible-lint yamllint`). +- Current active stack in `site.yml`: `dotfiles_common`, `packages_void`, `services_runit`, `profile_desktop_i3`. +- Use `--tags` for targeted runs when tags are available. +- Minimum dependencies: Python 3, Ansible, host access (local or SSH). +- Setup example: `python3 -m pip install ansible`. ## Code style guidelines ### Core principles -- Keep automation idempotent, declarative, and host-safe. -- Preserve variable layering: `all -> OS -> profile -> host`. -- Keep edits minimal and local; avoid opportunistic refactors. -- Prefer readability over compression in YAML/Jinja. +- Prefer idempotent, declarative, host-safe automation. +- Preserve layering: `all -> OS -> profile -> host`. +- Keep edits minimal and scoped to user intent. +- Avoid speculative refactors unrelated to the requested change. +- Optimize for readability over clever Jinja/YAML compression. -### Modules, imports, and role structure +### Modules, imports, and task structure - Use FQCN modules (`ansible.builtin.copy`, `community.general.xbps`). -- Prefer modules over `ansible.builtin.shell`/`ansible.builtin.command`. -- If command/shell is necessary, document intent via task name and guards. -- Keep `ansible/site.yml` orchestration-focused; implementation belongs in roles. -- Split large role task files with `import_tasks`/`include_tasks`. -- Keep each role narrow in purpose (packages, services, profile, dotfiles). +- Prefer modules over `ansible.builtin.command`/`ansible.builtin.shell`. +- Use `command`/`shell` only when no module fits; explain intent in task name. +- When using `command`/`shell`, set `changed_when` and `failed_when` as needed. +- Keep `ansible/site.yml` orchestration-only; implementation belongs in roles. +- Keep roles focused by domain (packages, services, profile, dotfiles). +- Split large task files with `import_tasks`/`include_tasks`. -### YAML formatting -- Start YAML files with `---`. -- Use 2-space indentation, never tabs. +### YAML formatting and file hygiene +- Start YAML documents with `---`. +- Use 2-space indentation; never tabs. - Keep key ordering stable and meaningful. -- Quote file modes as strings: `"0644"`, `"0755"`, `"0600"`, `"0700"`. -- Keep long Jinja expressions multiline. -- Avoid trailing whitespace. +- Quote file modes as strings (`"0644"`, `"0755"`, `"0600"`, `"0700"`). +- Use multiline Jinja for long expressions. +- Avoid trailing whitespace and noisy reformatting. -### Variables and types -- Use `snake_case` variable names. +### Variables, types, and templating +- Use `snake_case` variables. - Use semantically scoped names (`common_packages`, `void_packages_base`, `host_packages`). -- Keep booleans as `true`/`false`, not quoted strings. -- Keep lists and dicts as real YAML collections. -- Use `default([])` / `default({})` for optional variables. -- Build paths consistently from `{{ user_home }}` and related vars. +- Keep booleans as real booleans (`true`/`false`), not quoted strings. +- Keep lists/maps as YAML collections, not comma-separated strings. +- Use guards for optional values: `default([])`, `default({})`. +- Build home-relative paths from `{{ user_home }}` consistently. - Put shared defaults in `group_vars/all.yml`; specialize in group/host vars. ### Naming conventions -- Role directories: lowercase with underscores. -- Task names: imperative and outcome-based (`Enable host runit services`). -- Inventory group names and matching var filenames should stay aligned. +- Role directory names: lowercase with underscores. +- Task names: imperative and outcome-based. +- Keep inventory group names and var file names aligned. - Host var filenames must match hostnames exactly. ### Error handling and safety -- Guard OS/profile-specific steps with `when`. -- Use explicit `loop` inputs and default guards for optional lists. -- For `command`/`shell`, define `changed_when` and `failed_when` when needed. -- Do not suppress failures unless there is a clear operational reason. +- Guard OS/profile-specific behavior with `when`. +- Prefer explicit `loop` inputs; avoid implicit assumptions. +- Do not suppress failures without a clear operational reason. - Validate risky changes with `--check --diff` before full apply. -- Avoid destructive file operations in user homes unless explicitly required. -- Avoid touching secrets material; never commit credentials. +- Avoid destructive operations in user homes unless explicitly required. +- Never commit credentials or contents from `secrets/`. -### Dotfiles and shell scripts +### Dotfiles and shell script style - Prefer POSIX `sh`; use Bash only when required. -- If Bash is required, use shebang `#!/usr/bin/env bash`. +- Bash scripts should use `#!/usr/bin/env bash`. - Quote expansions (`"$var"`) unless intentional splitting is required. -- Keep scripts non-interactive when invoked by automation. +- Keep scripts non-interactive when run by automation. +- Preserve executable bits on scripts copied with `mode: preserve`. -## Agent expectations +## Agent workflow expectations - Do not modify unrelated files. -- Never commit or expose data from `secrets/`. -- Keep `AGENTS.md` and `README.md` in sync with workflow changes. -- When adding new role domains, add tags to support targeted execution. +- Verify assumptions by reading inventory, vars, and active roles before editing. +- Keep AGENTS and README aligned when workflow or commands change. +- When adding new domains/roles, also add tagging and validation guidance. ## Pre-merge checklist -Run before submitting changes: +Run before proposing or finalizing changes: ```bash ansible-playbook ansible/site.yml --syntax-check ansible-playbook ansible/site.yml --check --diff --limit