From bbe5bb8bdbb7771e3d0cb8716f824e43959a07b3 Mon Sep 17 00:00:00 2001 From: Fabio Scotto di Santolo Date: Fri, 27 Mar 2026 14:33:03 +0100 Subject: [PATCH] Document repo workflow for agents --- AGENTS.md | 249 +++++++++++++++++++++++++++--------------------------- TODOs.md | 3 + 2 files changed, 127 insertions(+), 125 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 00e58a2..77fbb73 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,56 +1,60 @@ # AGENTS.md -Guidance for agentic coding tools working in this repository. -Project type: Ansible-based infrastructure and user dotfiles. - -## Repository snapshot +Guidance for coding agents working in this repository. +Project type: Ansible-driven infrastructure, workstation/server provisioning, and user dotfiles. +## Repository Map - Entry playbook: `ansible/site.yml` - Inventory: `ansible/inventory/hosts.yml` -- Group vars: `ansible/inventory/group_vars/*.yml` -- Host vars: `ansible/inventory/host_vars/*.yml` +- Shared vars: `ansible/inventory/group_vars/*.yml` +- Host overrides: `ansible/inventory/host_vars/*.yml` +- Roles: `ansible/roles/*` - Templates: `ansible/templates/**/*.j2` -- Dotfiles source of truth: `dotfiles/` -- Utility scripts: `scripts/` -- Sensitive material/examples: `secrets/` - -## Active orchestration +- Dotfiles: `dotfiles/` +- Scripts: `scripts/` +- Local secrets area: `secrets/` +## Active Topology +- Void desktops: `ikaros`, `nymph` +- Ubuntu workstation: `deadalus` +- Ubuntu server: `prometheus` +- Most hosts currently use `ansible_connection: local` +## Active Orchestration `ansible/site.yml` currently applies: - `all -> dotfiles_common` - `void -> packages_void, services_runit, profile_desktop_i3` - `ubuntu_workstation -> packages_ubuntu, services_systemd, profile_workstation_gnome` - `ubuntu_server -> packages_ubuntu, services_systemd, profile_server` -Active roles: -- `dotfiles_common`, `packages_void`, `services_runit`, `profile_desktop_i3`, `packages_ubuntu`, `services_systemd`, `profile_workstation_gnome`, `profile_server` - Roles present but not wired into `ansible/site.yml`: - `base` - `dotfiles` - -## Local instruction files -Checked in this repository when this file was written: +## Local Instruction Files +Checked when this file was updated: - `.cursorrules`: not present - `.cursor/rules/`: not present - `.github/copilot-instructions.md`: not present -If any of these appear later, treat them as higher-priority local instructions. - -## Working assumptions -- Favor idempotent, host-safe changes over cleverness. -- Preserve the layering: `all -> OS -> profile -> host`. -- Validate on one host before broad rollout. -- Prefer minimal, targeted edits over cleanup refactors. -- Treat `secrets/` as sensitive and avoid exposing values. -- `dotfiles/common/.tmux/plugins/` contains vendored upstream code. - -## Build, lint, and test commands -There is no compile/build step. Validation is based on syntax checks, inventory inspection, dry-runs, and linting. - +If any appear later, treat them as higher-priority repo-local instructions. +## Working Principles +- Preserve the layering: `all -> OS -> profile -> host` +- Prefer minimal, targeted edits over cleanup refactors +- Preserve idempotency and reproducibility +- Validate on one limited host before broad rollout +- Treat `secrets/` as sensitive and never print secret values +- Avoid editing vendored code under `dotfiles/common/.tmux/plugins/` unless explicitly asked +## Build, Lint, And Test Commands +There is no compile/build pipeline. Confidence comes from syntax checks, dry runs, linting, and targeted script validation. Install tooling if needed: ```bash -python3 -m pip install ansible +python3 -m pip install ansible ansible-lint yamllint ansible-galaxy collection install community.general ``` - -Linting and static checks if available locally: +Core validation: +```bash +ansible-playbook ansible/site.yml --syntax-check +ansible-playbook ansible/site.yml --limit deadalus --check --diff +ansible-playbook ansible/site.yml --limit prometheus --check --diff +ansible-playbook ansible/site.yml --limit ikaros --check --diff +ansible-playbook ansible/site.yml --limit nymph --check --diff +``` +Linting and script checks: ```bash ansible-lint ansible/site.yml ansible-lint ansible/roles @@ -58,104 +62,99 @@ yamllint ansible/ sh -n scripts/bootstrap_mail.sh shellcheck scripts/bootstrap_mail.sh ``` - -## Single-test equivalents -There is no Molecule, pytest, or dedicated unit-test suite. Use the narrowest validation that matches the change. - -Fastest confidence check: +Useful execution commands: ```bash -ansible-playbook ansible/site.yml --syntax-check +ansible-playbook ansible/site.yml +ansible-playbook ansible/site.yml --limit deadalus +scripts/bootstrap_mail.sh ``` - -Best default dry-runs: -```bash -ansible-playbook ansible/site.yml --limit ikaros --check --diff -ansible-playbook ansible/site.yml --limit deadalus --check --diff -ansible-playbook ansible/site.yml --limit prometheus --check --diff -``` - -Testing notes: -- Prefer `--limit` aggressively to avoid accidental multi-host rollout. -- Prefer `--check --diff` before package, service, PAM, bootloader, firewall, or session changes. -- Keep task names stable and unique enough for `--start-at-task`. -- If you change only vars, inventory inspection may be the quickest useful check. - -## Code style guidelines -### General principles -- Keep orchestration in playbooks and implementation details in roles. -- Prefer declarative modules over imperative commands. -- Avoid unrelated refactors while solving a targeted task. -- Preserve idempotency and make state transitions explicit. - -### Ansible modules and task structure -- Use FQCN module names such as `ansible.builtin.copy` and `community.general.ufw`. -- Prefer purpose-built modules over `ansible.builtin.command` or `ansible.builtin.shell`. -- Use `command` only when no good module exists; use `shell` only when shell features are required. -- When using `command` or `shell`, set `changed_when` and `failed_when` when defaults are misleading. -- Keep task names imperative, outcome-based, and unique enough for `--start-at-task`. -- Tag every task consistently with its execution flow, typically `packages`, `services`, `dotfiles`, `gnome`, `nvidia`, or `dotfiles:*`. -- Prefer `loop` with clear `loop_control.label` for user-facing collections. - -### YAML formatting -- Start YAML files with `---`. -- Use 2-space indentation and never tabs. -- Keep keys, lists, and maps in stable order. -- Quote file modes as strings: `"0644"`, `"0755"`, `"0600"`, `"0700"`. -- Avoid formatting-only churn in untouched sections. - -### Variables, types, and naming -- Use `snake_case` consistently for variables and facts. -- Follow existing families such as `common_packages`, `profile_packages`, `host_packages`, `common_dotfiles`, `workstation_dotfiles`, `server_dotfiles`, and `host_dotfiles`. -- Keep booleans as booleans, not quoted strings. -- Keep structured data as YAML collections, not comma-separated strings. -- Guard optional collections/maps with `default([])` and `default({})`. -- Guard optional strings with `default('')`. -- Build user paths from `{{ user_home }}` instead of hardcoding home directories. -- Host-specific overrides belong in `host_vars`, not shared group files. - -### Error handling and safety -- Guard OS-specific or profile-specific behavior with `when` clauses. -- Prefer explicit inputs over assumptions about host state. -- Use `failed_when: false` only for intentional probes or best-effort detection. -- Use `no_log: true` for secrets, passwords, and sensitive command results. -- Keep tasks non-interactive and automation-safe. -- Avoid destructive operations in user homes unless clearly required. -- Fail early with `ansible.builtin.fail` when prerequisites such as architecture, release metadata, or session bus data are missing. -- For firewall changes, allow required access before enabling the firewall. - -### Shell, scripts, and external code -- Prefer POSIX `sh` for simple scripts; use Bash only when Bash features are required. -- Quote variable expansions unless intentional word splitting is required. -- Preserve executable bits for deployed scripts where appropriate. -- If you add Python later, follow standard-library, third-party, local import grouping. -- Treat vendored tmux plugins as upstream code unless the task explicitly targets them. - -## Editing guidance by area -- `ansible/site.yml`: keep it small and orchestration-focused. -- `ansible/inventory/group_vars/*.yml`: shared defaults by layer. -- `ansible/inventory/host_vars/*.yml`: host-specific overrides only. -- `ansible/roles/*/tasks/main.yml`: role implementation details. -- `ansible/templates/**/*.j2`: keep secrets and host-specific values parameterized. -- `dotfiles/`: user-facing config and session scripts deployed by roles. -- `scripts/`: standalone local utilities; keep them safe to run manually. - -## Validation expectations before finishing -Run the narrowest useful checks for the area you changed. - +## Single-Test Equivalents +There is no pytest, Molecule, or unit-test suite. Use the narrowest command matching the changed area. +- Single playbook syntax test: `ansible-playbook ansible/site.yml --syntax-check` +- Single host check: `ansible-playbook ansible/site.yml --limit --check --diff` +- Single task restart point: `ansible-playbook ansible/site.yml --limit --start-at-task "" --check --diff` +- Single script syntax test: `sh -n scripts/bootstrap_mail.sh` +- Single script lint: `shellcheck scripts/bootstrap_mail.sh` +When changing one area, prefer: +- vars or inventory: one limited host dry run +- one role: one limited host dry run, plus `ansible-lint ansible/roles/` if available +- one template: one limited host dry run with `--diff` +- one script: `sh -n` and `shellcheck` on that script +## Code Style Guidelines +### General +- Keep orchestration in playbooks and implementation in roles +- Prefer declarative modules over imperative shell commands +- Make state transitions explicit +- Avoid unrelated refactors in the same change +- Keep comments sparse and only for non-obvious behavior +### YAML And Formatting +- Start YAML files with `---` +- Use 2-space indentation; never use tabs +- Keep existing ordering stable when editing lists and maps +- Quote file modes as strings such as `"0644"`, `"0755"`, `"0600"`, `"0700"` +- Avoid formatting-only churn in untouched sections +### Imports, Modules, And Task Structure +- Use FQCN module names such as `ansible.builtin.copy` and `community.general.ufw` +- Prefer dedicated modules over `ansible.builtin.command` or `ansible.builtin.shell` +- Use `command` only when no module fits; use `shell` only for shell features +- When using `command` or `shell`, set `changed_when` and `failed_when` when defaults are misleading +- Keep task names imperative, descriptive, and stable enough for `--start-at-task` +- Tag tasks consistently with existing families such as `packages`, `services`, `dotfiles`, `gnome`, and `dotfiles:*` +- Prefer `loop` with `loop_control.label` for multi-item tasks +### Variables, Types, And Naming +- Use `snake_case` for vars, facts, and registered values +- Follow existing families such as `common_packages`, `ubuntu_packages_base`, `profile_packages`, `host_packages`, `workstation_dotfiles`, and `host_enabled_services` +- Keep booleans as booleans, not quoted strings +- Keep structured values as YAML lists/maps, not comma-separated strings +- Guard optional lists with `default([])`, mappings with `default({})`, and strings with `default('')` +- Build managed-user paths from `{{ user_home }}` +- Put host-specific overrides in `host_vars`, not shared `group_vars` +### Templates And Dotfiles +- Keep secrets parameterized through vars; never hardcode them in templates +- Preserve destination paths and permissions unless the task requires a change +- For workstation-only files, prefer `group_vars/workstation.yml` and the workstation role +- For server-only changes, keep them out of workstation profiles +- Do not modify Git templates unless the task explicitly concerns Git behavior +### Area-Specific Guidance +- `ansible/site.yml`: orchestration only; keep it small +- `ansible/inventory/group_vars/*.yml`: shared defaults by scope +- `ansible/inventory/host_vars/*.yml`: host-specific deltas only +- `ansible/roles/*/tasks/main.yml`: implementation details and ordered steps +- `ansible/templates/**/*.j2`: parameterized config files +- `dotfiles/`: deployed user config and session scripts +- `scripts/`: local helper scripts that should remain safe for manual execution +### Error Handling And Safety +- Fail early with `ansible.builtin.fail` when prerequisites are missing +- Guard OS-specific, DE-specific, and host-specific behavior with `when` +- Use `no_log: true` for passwords, tokens, and secret-bearing command results +- Use `failed_when: false` only for intentional probes +- Keep tasks non-interactive unless explicitly user-driven +- Avoid destructive changes in user homes unless clearly required +- For firewall changes, allow required access before enabling the firewall +### Shell Script Style +- Prefer POSIX `sh` for simple scripts; use Bash only when needed +- Use `set -eu` in POSIX shell scripts unless there is a reason not to +- Quote variable expansions unless intentional splitting is required +- Use helper functions for repeated checks and cleanup +## Validation Expectations Before Finishing +Run the narrowest useful checks for the files you changed. Default minimum: ```bash ansible-playbook ansible/site.yml --syntax-check ``` - -Preferred for role, template, or vars changes: +Preferred for vars, templates, roles, packages, services, PAM, GNOME, mail, firewall, or dotfile changes: ```bash ansible-playbook ansible/site.yml --limit --check --diff ``` - -## Agent workflow expectations -- Read the relevant inventory, vars, role tasks, templates, and deployed dotfiles before editing. -- Do not change unrelated files to "clean things up". -- 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. -- Prefer host-limited validation before broad apply. -- Call out any verification you could not run. +If you touched `scripts/bootstrap_mail.sh`, also run: +```bash +sh -n scripts/bootstrap_mail.sh +shellcheck scripts/bootstrap_mail.sh +``` +## Agent Workflow Expectations +- Read the relevant inventory, vars, role tasks, templates, and dotfiles before editing +- Do not revert unrelated worktree changes made by the user +- 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 +- Prefer host-limited validation first, especially `deadalus` for workstation work and `prometheus` for server work +- Call out checks you could not run and any follow-up verification needed diff --git a/TODOs.md b/TODOs.md index 4dbee96..ff9d697 100644 --- a/TODOs.md +++ b/TODOs.md @@ -10,3 +10,6 @@ - [x] scaricare la posta - [x] init mu per la ricerca - [ ] configurare GNOME +- [ ] verificare pacchetti YubiKey/GPG/SSH-FIDO2 sulla workstation Ubuntu +- [ ] configurare YubiKey per GPG signing sulla workstation +- [ ] valutare generazione chiave SSH ed25519-sk sulla workstation