mirror of
https://github.com/fscotto/infra.git
synced 2026-05-30 15:39:58 +00:00
Improve AGENTS.md and README.md with validation commands and workflow guidance
This commit is contained in:
57
AGENTS.md
57
AGENTS.md
@@ -7,9 +7,9 @@ Project type: Ansible-driven infrastructure, workstation/server provisioning, an
|
|||||||
- Inventory: `ansible/inventory/hosts.yml`
|
- Inventory: `ansible/inventory/hosts.yml`
|
||||||
- Group vars: `ansible/inventory/group_vars/*.yml`
|
- Group vars: `ansible/inventory/group_vars/*.yml`
|
||||||
- Host vars: `ansible/inventory/host_vars/*.yml`
|
- Host vars: `ansible/inventory/host_vars/*.yml`
|
||||||
|
- Shared templates: `ansible/templates/**/*.j2`
|
||||||
- Roles: `ansible/roles/*`
|
- Roles: `ansible/roles/*`
|
||||||
- Role assets: `ansible/roles/*/{tasks,templates,files,handlers}/`
|
- Role assets: `ansible/roles/*/{tasks,templates,files,handlers}/`
|
||||||
- Templates: `ansible/templates/**/*.j2`
|
|
||||||
- Dotfiles: `dotfiles/`
|
- Dotfiles: `dotfiles/`
|
||||||
- Scripts: `scripts/`
|
- Scripts: `scripts/`
|
||||||
- Secrets: `secrets/`
|
- Secrets: `secrets/`
|
||||||
@@ -19,38 +19,36 @@ Project type: Ansible-driven infrastructure, workstation/server provisioning, an
|
|||||||
- Ubuntu workstation: `deadalus`
|
- Ubuntu workstation: `deadalus`
|
||||||
- Ubuntu server: `prometheus`
|
- Ubuntu server: `prometheus`
|
||||||
- Most hosts use `ansible_connection: local`
|
- Most hosts use `ansible_connection: local`
|
||||||
- `all -> dotfiles_common`
|
- Current playbook layering: `all -> dotfiles_common`, `void -> packages_void + services_runit + profile_desktop_common + profile_desktop_i3 + profile_desktop_hyprland + profile_desktop_host`, `ubuntu_workstation -> packages_ubuntu + services_systemd + profile_workstation_gnome`, `ubuntu_server -> packages_ubuntu + services_systemd + profile_server`
|
||||||
- `void -> packages_void, services_runit, profile_desktop_common, profile_desktop_i3, profile_desktop_hyprland, profile_desktop_host`
|
- Present but currently unwired roles: `base`, `dotfiles`
|
||||||
- `ubuntu_workstation -> packages_ubuntu, services_systemd, profile_workstation_gnome`
|
|
||||||
- `ubuntu_server -> packages_ubuntu, services_systemd, profile_server`
|
|
||||||
- Present but unwired roles: `base`, `dotfiles`
|
|
||||||
|
|
||||||
## Local Instruction Files
|
## Local Instruction Files
|
||||||
Checked when this file was updated:
|
Checked when this file was updated:
|
||||||
- `.cursorrules`: not present
|
- `.cursorrules`: not present
|
||||||
- `.cursor/rules/`: not present
|
- `.cursor/rules/`: not present
|
||||||
- `.github/copilot-instructions.md`: not present
|
- `.github/copilot-instructions.md`: not present
|
||||||
If any appear later, treat them as higher-priority repo-local instructions.
|
If any of these files appear later, treat them as higher-priority repo-local instructions.
|
||||||
|
|
||||||
## Working Principles
|
## Working Principles
|
||||||
- Preserve the layering: `all -> OS -> profile -> host`
|
- Preserve the layering `all -> OS -> profile -> host`
|
||||||
- Prefer minimal, targeted edits over broad cleanup
|
- Prefer minimal, targeted edits over cleanup or refactors
|
||||||
- Preserve idempotency and reproducibility
|
- Preserve idempotency and reproducibility
|
||||||
- Validate on one limited host before broad rollout
|
- Validate on one limited host before broad rollout
|
||||||
- Treat `secrets/` as sensitive; never print secret values
|
- Treat `secrets/` as sensitive; never print secret values
|
||||||
- Avoid editing vendored code under `dotfiles/common/.tmux/plugins/` unless explicitly asked
|
- Avoid editing vendored code under `dotfiles/common/.tmux/plugins/` unless explicitly asked
|
||||||
- Keep `ansible/site.yml` small; orchestration belongs there, implementation belongs in roles
|
- Keep `ansible/site.yml` small; orchestration belongs there, implementation belongs in roles
|
||||||
|
- Read the relevant inventory, vars, role tasks, templates, files, handlers, and dotfiles before editing
|
||||||
|
|
||||||
## Build, Lint, And Test Commands
|
## Build, Lint, And Test Commands
|
||||||
There is no compile/build pipeline. Confidence comes from syntax checks, dry runs, linting, and targeted script validation.
|
There is no compile/build pipeline. Confidence comes from syntax checks, dry runs, linting, and targeted shell validation.
|
||||||
|
|
||||||
Install tooling if needed:
|
Install tooling if needed:
|
||||||
```bash
|
```bash
|
||||||
python3 -m pip install ansible ansible-lint yamllint
|
python3 -m pip install ansible ansible-lint yamllint shellcheck-py
|
||||||
ansible-galaxy collection install community.general
|
ansible-galaxy collection install community.general
|
||||||
```
|
```
|
||||||
|
|
||||||
Core validation:
|
Core validation from the repo root:
|
||||||
```bash
|
```bash
|
||||||
ansible-playbook ansible/site.yml --syntax-check
|
ansible-playbook ansible/site.yml --syntax-check
|
||||||
ansible-playbook ansible/site.yml --limit ikaros --check --diff
|
ansible-playbook ansible/site.yml --limit ikaros --check --diff
|
||||||
@@ -68,6 +66,7 @@ ansible-playbook ansible/site.yml
|
|||||||
ansible-playbook ansible/site.yml --limit ikaros
|
ansible-playbook ansible/site.yml --limit ikaros
|
||||||
ansible-playbook ansible/site.yml --limit nymph
|
ansible-playbook ansible/site.yml --limit nymph
|
||||||
ansible-playbook ansible/site.yml --limit deadalus
|
ansible-playbook ansible/site.yml --limit deadalus
|
||||||
|
ansible-playbook ansible/site.yml --limit prometheus
|
||||||
scripts/bootstrap_mail.sh
|
scripts/bootstrap_mail.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -75,9 +74,12 @@ scripts/bootstrap_mail.sh
|
|||||||
There is no pytest, Molecule, or unit-test suite. Use the narrowest command matching the changed area.
|
There is no pytest, Molecule, or unit-test suite. Use the narrowest command matching the changed area.
|
||||||
- Playbook syntax only: `ansible-playbook ansible/site.yml --syntax-check`
|
- Playbook syntax only: `ansible-playbook ansible/site.yml --syntax-check`
|
||||||
- Single host dry run: `ansible-playbook ansible/site.yml --limit <host> --check --diff`
|
- Single host dry run: `ansible-playbook ansible/site.yml --limit <host> --check --diff`
|
||||||
|
- Single host, selected tags: `ansible-playbook ansible/site.yml --limit <host> --tags <tag1>,<tag2> --check --diff`
|
||||||
- Single task restart point: `ansible-playbook ansible/site.yml --limit <host> --start-at-task "<task name>" --check --diff`
|
- Single task restart point: `ansible-playbook ansible/site.yml --limit <host> --start-at-task "<task name>" --check --diff`
|
||||||
- Single role lint: `ansible-lint ansible/roles/<role>`
|
- Single role lint: `ansible-lint ansible/roles/<role>`
|
||||||
|
- Single YAML file lint: `yamllint ansible/path/to/file.yml`
|
||||||
- Script syntax/lint: `sh -n scripts/bootstrap_mail.sh` and `shellcheck scripts/bootstrap_mail.sh`
|
- Script syntax/lint: `sh -n scripts/bootstrap_mail.sh` and `shellcheck scripts/bootstrap_mail.sh`
|
||||||
|
- For shell changes outside vendored tmux plugins, prefer validating the touched file with `sh -n` and `shellcheck`
|
||||||
- Prefer one limited-host dry run for vars, templates, dotfiles, packages, services, PAM, display manager, and firewall changes
|
- Prefer one limited-host dry run for vars, templates, dotfiles, packages, services, PAM, display manager, and firewall changes
|
||||||
|
|
||||||
## Code Style Guidelines
|
## Code Style Guidelines
|
||||||
@@ -95,18 +97,19 @@ There is no pytest, Molecule, or unit-test suite. Use the narrowest command matc
|
|||||||
- Quote file modes as strings such as `"0644"`, `"0755"`, `"0600"`, `"0700"`
|
- Quote file modes as strings such as `"0644"`, `"0755"`, `"0600"`, `"0700"`
|
||||||
- Avoid formatting-only churn in untouched sections
|
- Avoid formatting-only churn in untouched sections
|
||||||
|
|
||||||
### Modules And Task Structure
|
### Modules, Imports, And Task Structure
|
||||||
- Use FQCN module names such as `ansible.builtin.copy` and `community.general.xbps`
|
- Use FQCN module names such as `ansible.builtin.copy`, `ansible.builtin.template`, and `community.general.xbps`
|
||||||
- Prefer dedicated modules over `ansible.builtin.command` or `ansible.builtin.shell`
|
- Prefer dedicated modules over `ansible.builtin.command` or `ansible.builtin.shell`
|
||||||
- Use `command` only when no module fits; use `shell` only for shell features
|
- Use `command` only when no module fits; use `shell` only when shell features are required
|
||||||
- When using `command` or `shell`, set `changed_when` and `failed_when` when defaults are misleading
|
- When using `command` or `shell`, set `changed_when` and `failed_when` when defaults are misleading
|
||||||
|
- Prefer `ansible.builtin.import_tasks` for static task composition and `include_tasks` only for dynamic or conditional includes
|
||||||
- Keep task names imperative, descriptive, and stable enough for `--start-at-task`
|
- Keep task names imperative, descriptive, and stable enough for `--start-at-task`
|
||||||
- Tag tasks consistently with existing families such as `packages`, `services`, `dotfiles`, `gnome`, `nvidia`, `emptty`, and `dotfiles:*`
|
- Tag tasks consistently with existing families such as `packages`, `services`, `dotfiles`, `gnome`, `nvidia`, `emptty`, and `dotfiles:*`
|
||||||
- Prefer `loop` with `loop_control.label` for multi-item tasks
|
- Prefer `loop` with `loop_control.label` for multi-item tasks
|
||||||
- Use handlers for service restarts when configuration changes should trigger them
|
- Use handlers for service restarts when configuration changes should trigger them
|
||||||
|
|
||||||
### Variables, Types, And Naming
|
### Variables, Types, And Naming
|
||||||
- Use `snake_case` for vars, facts, and registered values
|
- Use `snake_case` for vars, facts, registered values, and custom facts
|
||||||
- Follow existing families such as `common_packages`, `profile_packages`, `host_packages`, `desktop_common_packages`, `desktop_i3_packages`, `desktop_hyprland_packages`, `desktop_common_dotfiles`, `desktop_i3_dotfiles`, `desktop_hyprland_dotfiles`, `host_i3_dotfiles`, `host_hyprland_dotfiles`, `enabled_services`, and `host_enabled_services`
|
- Follow existing families such as `common_packages`, `profile_packages`, `host_packages`, `desktop_common_packages`, `desktop_i3_packages`, `desktop_hyprland_packages`, `desktop_common_dotfiles`, `desktop_i3_dotfiles`, `desktop_hyprland_dotfiles`, `host_i3_dotfiles`, `host_hyprland_dotfiles`, `enabled_services`, and `host_enabled_services`
|
||||||
- Keep booleans as booleans, not quoted strings
|
- Keep booleans as booleans, not quoted strings
|
||||||
- Keep structured values as YAML lists/maps, not comma-separated strings
|
- Keep structured values as YAML lists/maps, not comma-separated strings
|
||||||
@@ -115,37 +118,42 @@ There is no pytest, Molecule, or unit-test suite. Use the narrowest command matc
|
|||||||
- Put host-specific overrides in `host_vars`, not shared `group_vars`
|
- Put host-specific overrides in `host_vars`, not shared `group_vars`
|
||||||
|
|
||||||
### Templates, Dotfiles, And Shell
|
### Templates, Dotfiles, And Shell
|
||||||
- Keep secrets parameterized through vars; never hardcode them in templates
|
- Keep secrets parameterized through vars; never hardcode them in templates or dotfiles
|
||||||
- Prefer role `templates/` for variable-driven config and role `files/` for static payloads
|
- Prefer role `templates/` for variable-driven config and role `files/` for static payloads
|
||||||
- Preserve destination paths and permissions unless the task requires a change
|
- Preserve destination paths and permissions unless the task requires a change
|
||||||
- Dotfiles should stay deployable on real machines; avoid repo-only hacks in `dotfiles/`
|
- Dotfiles should stay deployable on real machines; avoid repo-only hacks in `dotfiles/`
|
||||||
- Prefer POSIX `sh` for simple scripts; use Bash only when needed
|
- Prefer POSIX `sh` for simple scripts; use Bash only when needed
|
||||||
- Use `set -eu` in POSIX shell scripts unless there is a clear reason not to
|
- Use `set -eu` in POSIX shell scripts unless there is a clear reason not to
|
||||||
- Quote variable expansions unless intentional splitting is required
|
- Quote variable expansions unless intentional splitting is required
|
||||||
|
- Do not modernize vendored shell code under tmux plugins unless explicitly asked
|
||||||
|
|
||||||
### Error Handling And Safety
|
### Error Handling, Safety, And Idempotency
|
||||||
- Fail early with `ansible.builtin.fail` when prerequisites are missing
|
- Fail early with `ansible.builtin.fail` when prerequisites are missing
|
||||||
- Guard OS-specific, DE-specific, and host-specific behavior with `when`
|
- Guard OS-specific, DE-specific, and host-specific behavior with `when`
|
||||||
- Use `no_log: true` for passwords, tokens, and secret-bearing command results
|
- Use `no_log: true` for passwords, tokens, private keys, and secret-bearing command results
|
||||||
- Use `failed_when: false` only for intentional probes
|
- Use `failed_when: false` only for intentional probes
|
||||||
- Keep tasks non-interactive unless explicitly user-driven
|
- Keep tasks non-interactive unless explicitly user-driven
|
||||||
- Avoid destructive changes in user homes unless clearly required
|
- Avoid destructive changes in user homes unless clearly required
|
||||||
- For firewall changes, allow required access before enabling the firewall
|
- For firewall changes, allow required access before enabling the firewall
|
||||||
- Be careful with display-manager/session changes on desktop hosts; validate on one host first
|
- Be careful with display-manager and session changes on desktop hosts; validate on one host first
|
||||||
|
- When running commands as the desktop user, set `become_user` and the required `HOME` or session environment explicitly
|
||||||
|
|
||||||
## Area-Specific Notes
|
## Area-Specific Notes
|
||||||
- `profile_desktop_common` manages `emptty` and the shared Void desktop bootstrap; `profile_desktop_i3` adds the X11/i3 session; `profile_desktop_hyprland` adds the optional Wayland session on hosts that enable it; `profile_desktop_host` carries host-specific desktop overrides such as NVIDIA or host session dotfiles
|
- `profile_desktop_common` manages shared Void desktop bootstrap, `emptty`, PAM hooks, dotfiles, mail bootstrap, and shared desktop tooling
|
||||||
|
- `profile_desktop_i3` contains the X11/i3 session pieces
|
||||||
|
- `profile_desktop_hyprland` contains the optional Hyprland/Wayland session pieces
|
||||||
|
- `profile_desktop_host` carries host-specific desktop overrides such as NVIDIA, PRIME wrappers, and host-only WirePlumber config
|
||||||
- Do not auto-restart `emptty` during playbook runs on active desktop hosts; prefer a manual restart from SSH or another TTY after the run
|
- Do not auto-restart `emptty` during playbook runs on active desktop hosts; prefer a manual restart from SSH or another TTY after the run
|
||||||
- `dotfiles/desktop/.xinitrc` is part of the X11 session bootstrap path; changes there affect login behavior
|
- `dotfiles/desktop/.xinitrc` is part of the X11 session bootstrap path; changes there affect login behavior
|
||||||
- `dotfiles/desktop/.local/bin/start-hyprland-session` is the Wayland session bootstrap path; keep it aligned with DBus and keyring expectations
|
- `dotfiles/desktop/.local/bin/start-hyprland-session` is the Wayland session bootstrap path; keep it aligned with DBus and keyring expectations
|
||||||
- `nymph` has special NVIDIA/PRIME handling; keep host-specific logic guarded by hostname or host vars
|
- `nymph` has special NVIDIA/PRIME handling and a host-specific WirePlumber camera override; keep host logic guarded by hostname or host vars
|
||||||
- `ikaros` is treated as the more stable personal desktop; prefer validating risky desktop changes elsewhere first
|
|
||||||
|
|
||||||
## Validation Expectations Before Finishing
|
## Validation Expectations Before Finishing
|
||||||
Default minimum:
|
Default minimum:
|
||||||
```bash
|
```bash
|
||||||
ansible-playbook ansible/site.yml --syntax-check
|
ansible-playbook ansible/site.yml --syntax-check
|
||||||
```
|
```
|
||||||
|
Run a host-limited dry run whenever the change affects a real host profile, package set, service set, session, PAM stack, templates, or dotfiles.
|
||||||
If you touched `scripts/bootstrap_mail.sh`, also run:
|
If you touched `scripts/bootstrap_mail.sh`, also run:
|
||||||
```bash
|
```bash
|
||||||
sh -n scripts/bootstrap_mail.sh
|
sh -n scripts/bootstrap_mail.sh
|
||||||
@@ -153,9 +161,8 @@ shellcheck scripts/bootstrap_mail.sh
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Agent Workflow Expectations
|
## Agent Workflow Expectations
|
||||||
- Read the relevant inventory, vars, role tasks, templates, files, handlers, and dotfiles before editing
|
|
||||||
- Do not revert unrelated worktree changes made by the user
|
- Do not revert unrelated worktree changes made by the user
|
||||||
- Keep `README.md` and `AGENTS.md` aligned when workflows materially change
|
- Keep `README.md` and `AGENTS.md` aligned when workflows materially change
|
||||||
- If you add a new operational area, also add the validation command agents should run
|
- If you add a new operational area, also add the validation command agents should run
|
||||||
- Prefer host-limited validation first, especially `ikaros` or `nymph` for Void desktop work, `deadalus` for Ubuntu workstation work, and `prometheus` for server work
|
- Prefer host-limited validation first: `ikaros` or `nymph` for Void desktop work, `deadalus` for Ubuntu workstation work, and `prometheus` for server work
|
||||||
- Call out checks you could not run and any follow-up verification needed
|
- Call out checks you could not run and any follow-up verification needed
|
||||||
|
|||||||
26
README.md
26
README.md
@@ -243,13 +243,16 @@ Per utilizzare il repository sono necessari:
|
|||||||
|
|
||||||
- Python 3
|
- Python 3
|
||||||
- Ansible
|
- Ansible
|
||||||
|
- `ansible-lint`
|
||||||
|
- `yamllint`
|
||||||
|
- `shellcheck`
|
||||||
- collection `community.general`
|
- collection `community.general`
|
||||||
- accesso locale o SSH alle macchine target, in base a come e definito l'inventory
|
- accesso locale o SSH alle macchine target, in base a come e definito l'inventory
|
||||||
|
|
||||||
Installazione base:
|
Installazione base:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install ansible
|
python3 -m pip install ansible ansible-lint yamllint shellcheck-py
|
||||||
ansible-galaxy collection install community.general
|
ansible-galaxy collection install community.general
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -286,6 +289,18 @@ ansible-playbook ansible/site.yml --limit ikaros --check --diff
|
|||||||
ansible-playbook ansible/site.yml --limit nymph --check --diff
|
ansible-playbook ansible/site.yml --limit nymph --check --diff
|
||||||
ansible-playbook ansible/site.yml --limit deadalus --check --diff
|
ansible-playbook ansible/site.yml --limit deadalus --check --diff
|
||||||
ansible-playbook ansible/site.yml --limit prometheus --check --diff
|
ansible-playbook ansible/site.yml --limit prometheus --check --diff
|
||||||
|
ansible-lint ansible/site.yml
|
||||||
|
ansible-lint ansible/roles
|
||||||
|
yamllint ansible/
|
||||||
|
```
|
||||||
|
|
||||||
|
Per validazioni piu mirate:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-playbook ansible/site.yml --limit <host> --tags <tag1>,<tag2> --check --diff
|
||||||
|
ansible-playbook ansible/site.yml --limit <host> --start-at-task "<task name>" --check --diff
|
||||||
|
ansible-lint ansible/roles/<role>
|
||||||
|
yamllint ansible/path/to/file.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -296,7 +311,7 @@ Una nuova macchina può essere inizializzata con i seguenti passaggi:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone <repo>
|
git clone <repo>
|
||||||
cd infra
|
cd <repo-dir>
|
||||||
ansible-galaxy collection install community.general
|
ansible-galaxy collection install community.general
|
||||||
ansible-playbook ansible/site.yml
|
ansible-playbook ansible/site.yml
|
||||||
```
|
```
|
||||||
@@ -311,6 +326,13 @@ scripts/bootstrap_mail.sh
|
|||||||
|
|
||||||
Lo script si occupa del bootstrap dei secret nel keyring, del primo sync con `mbsync` e dell'inizializzazione di `mu` usando la configurazione mail generata dai template.
|
Lo script si occupa del bootstrap dei secret nel keyring, del primo sync con `mbsync` e dell'inizializzazione di `mu` usando la configurazione mail generata dai template.
|
||||||
|
|
||||||
|
Se modifichi questo script, valida almeno con:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sh -n scripts/bootstrap_mail.sh
|
||||||
|
shellcheck scripts/bootstrap_mail.sh
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Filosofia del progetto
|
# Filosofia del progetto
|
||||||
|
|||||||
Reference in New Issue
Block a user