{"owner":"netbootxyz","repo":"netboot.xyz","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# AGENTS.md\n\nGuidelines for AI coding agents working in the netboot.xyz repository.\n\n## Project Summary\n\nnetboot.xyz generates iPXE bootloaders and menus for 190+ operating systems using Ansible and Jinja2 templates. There is no application code in a traditional sense — the project produces `.ipxe` scripts and bootloader binaries.\n\n## Build Commands\n\n```bash\n# Syntax check (fast, run first)\nansible-playbook site.yml --syntax-check\n\n# Lint Ansible tasks\nansible-lint -v roles/netbootxyz/tasks\n\n# Full local build (generates menus + bootloaders to /var/www/html)\nansible-playbook site.yml\n\n# Menu-only build (skip bootloader compilation)\nansible-playbook site.yml -e \"generate_disks=false generate_checksums=false generate_signatures=false\"\n\n# Docker build (outputs to buildout/)\ndocker build -t localbuild --platform=linux/amd64 -f Dockerfile .\ndocker run --rm -it --platform=linux/amd64 -v $(pwd):/buildout localbuild\n\n# Release builds\n./script/build_release dev      # Development\n./script/build_release pr       # Pull request test\n./script/build_release rc       # Release candidate\n./script/build_release release  # Production\n./script/build_release rolling  # Rolling\n```\n\n### CI Checks (what PRs must pass)\n\n1. `ansible-playbook site.yml --syntax-check`\n2. `ansible-lint -v roles/netbootxyz/tasks`\n3. Full Docker build via `./script/build_release pr`\n\n### Testing\n\nMolecule tests exist but require Docker:\n```bash\npip install molecule molecule-docker\nmolecule test\n```\n\nThere are no unit tests. Validation is done through syntax checks, linting, and full builds.\n\n## Code Style\n\n### YAML / Ansible\n\n- Start every YAML file with `---` on line 1.\n- Use 2-space indentation consistently.\n- Use **fully-qualified collection names** (FQCN) for all modules:\n  - `ansible.builtin.template`, `ansible.builtin.set_fact`, `ansible.builtin.shell`, etc.\n  - Never use short names like `template:` or `shell:`.\n- Use `snake_case` for all variable names: `boot_domain`, `generate_menus`, `netbootxyz_root`.\n- Guard booleans with the `| default(true) | bool` pattern:\n  ```yaml\n  when:\n    - generate_menus | default(true) | bool\n  ```\n- Use `when:` as a list even for single conditions.\n- Use descriptive `name:` for every task.\n- The `.ansible-lint` config skips these rules (do not add workarounds for them):\n  - `command-instead-of-module`, `command-instead-of-shell`\n  - `no-changed-when`, `risky-shell-pipe`\n  - `literal-compare`, `var-naming[no-role-prefix]`\n\n### iPXE Templates (`.ipxe.j2` files)\n\n- Start with `#!ipxe` shebang on line 1.\n- Add a comment header with OS name and URL on lines 2-4.\n- iPXE scripts are **flat** — do not indent iPXE commands.\n- Use `#` for comments inside templates.\n- Variable conventions:\n  - iPXE runtime variables: `${variable_name}` (evaluated at boot time)\n  - Jinja2 template variables: `{{ variable }}` (evaluated at build time)\n  - These are often mixed: `${live_endpoint}{{ endpoints.foo.path }}`\n- Labels use `:label_name` in `snake_case`.\n- Navigation pattern: `goto ${menu} ||` at template start.\n- User selection: `choose <var> || goto <exit_label>`.\n- Exit pattern: clear menu and `exit 0`:\n  ```ipxe\n  :distro_exit\n  clear menu\n  exit 0\n  ```\n- Error pattern: echo, prompt, return to menu:\n  ```ipxe\n  :error\n  echo Error occurred, press any key to return to menu\n  prompt\n  goto main_menu\n  ```\n- Fallback chains: `command || goto fallback` for graceful degradation.\n- Architecture mapping varies by OS family:\n  - Red Hat: `x86_64` → `x86_64`, `arm64` → `aarch64`\n  - Debian: `x86_64` → `amd64`, `arm64` → `arm64`\n- Guard optional values: `isset ${variable}` in iPXE, `{% if value.field is defined %}` in Jinja2.\n\n### Jinja2 Patterns\n\n- Loop over releases: `{% for item in releases.<distro>.versions %}`\n- Sort by name: `{% for key, value in releases.items() | sort(attribute='1.name') %}`\n- Filter enabled items: `{% if value.enabled is defined and value.enabled | bool %}`\n- Template iteration uses `with_community.general.filetree` in tasks.\n\n### OS Definition Schema (`defaults/main.yml`)\n\n```yaml\nreleases:\n  distro_key:          # lowercase, no hyphens (e.g., almalinux, rockylinux)\n    name: \"Display Name\"\n    mirror: \"http://mirror.url\"\n    base_dir: \"path/on/mirror\"\n    enabled: true\n    menu: linux         # one of: linux, bsd, dos, unix\n    versions:\n      - code_name: \"version_id\"\n        name: \"Display Version\"\n```\n\nOptional fields: `archive_mirror`, `paths`, `flavors`, `platforms`, `version`.\n\n### Utility Definition Schema (`defaults/main.yml`)\n\n```yaml\nutilitiesefi:          # or utilitiespcbios64, utilitiespcbios32, utilitiesarm\n  utility_key:\n    name: \"Display Name\"\n    enabled: true\n    type: direct        # one of: direct, ipxemenu, memdisk, memtest, sanboot\n    kernel: \"<url>\"\n    initrd: \"<url>\"     # optional\n```\n\n## File Organization\n\n| Path | Purpose |\n|------|---------|\n| `site.yml` | Main playbook entry point |\n| `defaults/main.yml` | All OS/utility definitions and default config |\n| `endpoints.yml` | Live image endpoint URLs |\n| `user_overrides.yml` | Local overrides (not committed) |\n| `templates/menu/*.ipxe.j2` | ~100 iPXE menu templates |\n| `templates/disks/*.j2` | Bootloader embedded scripts |\n| `templates/pipxe/*.j2` | Raspberry Pi Makefile templates |\n| `tasks/*.yml` | 14 Ansible task files |\n| `vars/{debian,redhat,ubuntu}.yml` | Per-distro package lists |\n| `script/` | Build and release shell scripts |\n\n## Menu Hierarchy\n\n```\nmenu.ipxe (main) → linux.ipxe → ubuntu.ipxe, fedora.ipxe, ...\n                  → bsd.ipxe   → freebsd.ipxe, openbsd.ipxe, ...\n                  → live.ipxe  → live-ubuntu.ipxe, ...\n                  → utils-*.ipxe\n                  → windows.ipxe\n```\n\nMenus chain via `chain ${menu}.ipxe || goto error`. Signature verification gates chaining when `sigs_enabled` is true.\n\n## Error Handling\n\n- **Ansible**: Relies on default fail-fast behavior. No `block/rescue/always`. Guard tasks with `when:` conditions. Use `| default()` to prevent undefined variable errors.\n- **iPXE**: Use `command || goto fallback` chains. Protocol degradation: HTTPS → HTTP → local boot. Always provide a `:error` label that prompts the user.\n- **Shell scripts**: Use `set -e` at the top of all scripts.\n\n## Adding a New Operating System\n\n1. Add entry to `releases:` in `roles/netbootxyz/defaults/main.yml`.\n2. Create `roles/netbootxyz/templates/menu/<distro>.ipxe.j2` following existing templates.\n3. The menu template is auto-discovered via `filetree` iteration — no registration needed.\n4. Add the distro to the appropriate category menu (e.g., `linux.ipxe.j2`) if it needs a menu entry.\n5. If using live images, add endpoint to `endpoints.yml`.\n6. Test: `ansible-playbook site.yml --syntax-check && ansible-lint -v roles/netbootxyz/tasks`\n\n## Key Variables\n\n- **`boot_domain`**: Target domain for generated menus.\n- **`boot_version`**: Version string for releases.\n- **`site_name`**: Custom branding (defaults to `netboot.xyz`).\n- **`generate_menus` / `generate_disks`**: Enable/disable build components.\n- **`sigs_enabled`**: Enable signature verification for menu chaining.\n- **`live_endpoint`**: Base URL for live/rescue images.\n- **Runtime variables**: `${distro}_mirror` and `${distro}_base_dir` are auto-generated from `releases:` entries in `boot.cfg.j2` and available to all menu templates at boot time.\n\n## Git Workflow\n\n- **`development`**: Main development branch, default PR target.\n- **`RC`**: Release candidate staging.\n- **`master`**: Production releases.\n- Commit style: imperative mood, descriptive. Automated commits use `Version bump for ...` format.\n"},"files":{"AGENTS.md":"# AGENTS.md\n\nGuidelines for AI coding agents working in the netboot.xyz repository.\n\n## Project Summary\n\nnetboot.xyz generates iPXE bootloaders and menus for 190+ operating systems using Ansible and Jinja2 templates. There is no application code in a traditional sense — the project produces `.ipxe` scripts and bootloader binaries.\n\n## Build Commands\n\n```bash\n# Syntax check (fast, run first)\nansible-playbook site.yml --syntax-check\n\n# Lint Ansible tasks\nansible-lint -v roles/netbootxyz/tasks\n\n# Full local build (generates menus + bootloaders to /var/www/html)\nansible-playbook site.yml\n\n# Menu-only build (skip bootloader compilation)\nansible-playbook site.yml -e \"generate_disks=false generate_checksums=false generate_signatures=false\"\n\n# Docker build (outputs to buildout/)\ndocker build -t localbuild --platform=linux/amd64 -f Dockerfile .\ndocker run --rm -it --platform=linux/amd64 -v $(pwd):/buildout localbuild\n\n# Release builds\n./script/build_release dev      # Development\n./script/build_release pr       # Pull request test\n./script/build_release rc       # Release candidate\n./script/build_release release  # Production\n./script/build_release rolling  # Rolling\n```\n\n### CI Checks (what PRs must pass)\n\n1. `ansible-playbook site.yml --syntax-check`\n2. `ansible-lint -v roles/netbootxyz/tasks`\n3. Full Docker build via `./script/build_release pr`\n\n### Testing\n\nMolecule tests exist but require Docker:\n```bash\npip install molecule molecule-docker\nmolecule test\n```\n\nThere are no unit tests. Validation is done through syntax checks, linting, and full builds.\n\n## Code Style\n\n### YAML / Ansible\n\n- Start every YAML file with `---` on line 1.\n- Use 2-space indentation consistently.\n- Use **fully-qualified collection names** (FQCN) for all modules:\n  - `ansible.builtin.template`, `ansible.builtin.set_fact`, `ansible.builtin.shell`, etc.\n  - Never use short names like `template:` or `shell:`.\n- Use `snake_case` for all variable names: `boot_domain`, `generate_menus`, `netbootxyz_root`.\n- Guard booleans with the `| default(true) | bool` pattern:\n  ```yaml\n  when:\n    - generate_menus | default(true) | bool\n  ```\n- Use `when:` as a list even for single conditions.\n- Use descriptive `name:` for every task.\n- The `.ansible-lint` config skips these rules (do not add workarounds for them):\n  - `command-instead-of-module`, `command-instead-of-shell`\n  - `no-changed-when`, `risky-shell-pipe`\n  - `literal-compare`, `var-naming[no-role-prefix]`\n\n### iPXE Templates (`.ipxe.j2` files)\n\n- Start with `#!ipxe` shebang on line 1.\n- Add a comment header with OS name and URL on lines 2-4.\n- iPXE scripts are **flat** — do not indent iPXE commands.\n- Use `#` for comments inside templates.\n- Variable conventions:\n  - iPXE runtime variables: `${variable_name}` (evaluated at boot time)\n  - Jinja2 template variables: `{{ variable }}` (evaluated at build time)\n  - These are often mixed: `${live_endpoint}{{ endpoints.foo.path }}`\n- Labels use `:label_name` in `snake_case`.\n- Navigation pattern: `goto ${menu} ||` at template start.\n- User selection: `choose <var> || goto <exit_label>`.\n- Exit pattern: clear menu and `exit 0`:\n  ```ipxe\n  :distro_exit\n  clear menu\n  exit 0\n  ```\n- Error pattern: echo, prompt, return to menu:\n  ```ipxe\n  :error\n  echo Error occurred, press any key to return to menu\n  prompt\n  goto main_menu\n  ```\n- Fallback chains: `command || goto fallback` for graceful degradation.\n- Architecture mapping varies by OS family:\n  - Red Hat: `x86_64` → `x86_64`, `arm64` → `aarch64`\n  - Debian: `x86_64` → `amd64`, `arm64` → `arm64`\n- Guard optional values: `isset ${variable}` in iPXE, `{% if value.field is defined %}` in Jinja2.\n\n### Jinja2 Patterns\n\n- Loop over releases: `{% for item in releases.<distro>.versions %}`\n- Sort by name: `{% for key, value in releases.items() | sort(attribute='1.name') %}`\n- Filter enabled items: `{% if value.enabled is defined and value.enabled | bool %}`\n- Template iteration uses `with_community.general.filetree` in tasks.\n\n### OS Definition Schema (`defaults/main.yml`)\n\n```yaml\nreleases:\n  distro_key:          # lowercase, no hyphens (e.g., almalinux, rockylinux)\n    name: \"Display Name\"\n    mirror: \"http://mirror.url\"\n    base_dir: \"path/on/mirror\"\n    enabled: true\n    menu: linux         # one of: linux, bsd, dos, unix\n    versions:\n      - code_name: \"version_id\"\n        name: \"Display Version\"\n```\n\nOptional fields: `archive_mirror`, `paths`, `flavors`, `platforms`, `version`.\n\n### Utility Definition Schema (`defaults/main.yml`)\n\n```yaml\nutilitiesefi:          # or utilitiespcbios64, utilitiespcbios32, utilitiesarm\n  utility_key:\n    name: \"Display Name\"\n    enabled: true\n    type: direct        # one of: direct, ipxemenu, memdisk, memtest, sanboot\n    kernel: \"<url>\"\n    initrd: \"<url>\"     # optional\n```\n\n## File Organization\n\n| Path | Purpose |\n|------|---------|\n| `site.yml` | Main playbook entry point |\n| `defaults/main.yml` | All OS/utility definitions and default config |\n| `endpoints.yml` | Live image endpoint URLs |\n| `user_overrides.yml` | Local overrides (not committed) |\n| `templates/menu/*.ipxe.j2` | ~100 iPXE menu templates |\n| `templates/disks/*.j2` | Bootloader embedded scripts |\n| `templates/pipxe/*.j2` | Raspberry Pi Makefile templates |\n| `tasks/*.yml` | 14 Ansible task files |\n| `vars/{debian,redhat,ubuntu}.yml` | Per-distro package lists |\n| `script/` | Build and release shell scripts |\n\n## Menu Hierarchy\n\n```\nmenu.ipxe (main) → linux.ipxe → ubuntu.ipxe, fedora.ipxe, ...\n                  → bsd.ipxe   → freebsd.ipxe, openbsd.ipxe, ...\n                  → live.ipxe  → live-ubuntu.ipxe, ...\n                  → utils-*.ipxe\n                  → windows.ipxe\n```\n\nMenus chain via `chain ${menu}.ipxe || goto error`. Signature verification gates chaining when `sigs_enabled` is true.\n\n## Error Handling\n\n- **Ansible**: Relies on default fail-fast behavior. No `block/rescue/always`. Guard tasks with `when:` conditions. Use `| default()` to prevent undefined variable errors.\n- **iPXE**: Use `command || goto fallback` chains. Protocol degradation: HTTPS → HTTP → local boot. Always provide a `:error` label that prompts the user.\n- **Shell scripts**: Use `set -e` at the top of all scripts.\n\n## Adding a New Operating System\n\n1. Add entry to `releases:` in `roles/netbootxyz/defaults/main.yml`.\n2. Create `roles/netbootxyz/templates/menu/<distro>.ipxe.j2` following existing templates.\n3. The menu template is auto-discovered via `filetree` iteration — no registration needed.\n4. Add the distro to the appropriate category menu (e.g., `linux.ipxe.j2`) if it needs a menu entry.\n5. If using live images, add endpoint to `endpoints.yml`.\n6. Test: `ansible-playbook site.yml --syntax-check && ansible-lint -v roles/netbootxyz/tasks`\n\n## Key Variables\n\n- **`boot_domain`**: Target domain for generated menus.\n- **`boot_version`**: Version string for releases.\n- **`site_name`**: Custom branding (defaults to `netboot.xyz`).\n- **`generate_menus` / `generate_disks`**: Enable/disable build components.\n- **`sigs_enabled`**: Enable signature verification for menu chaining.\n- **`live_endpoint`**: Base URL for live/rescue images.\n- **Runtime variables**: `${distro}_mirror` and `${distro}_base_dir` are auto-generated from `releases:` entries in `boot.cfg.j2` and available to all menu templates at boot time.\n\n## Git Workflow\n\n- **`development`**: Main development branch, default PR target.\n- **`RC`**: Release candidate staging.\n- **`master`**: Production releases.\n- Commit style: imperative mood, descriptive. Automated commits use `Version bump for ...` format.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# AGENTS.md\n\nGuidelines for AI coding agents working in the netboot.xyz repository.\n\n## Project Summary\n\nnetboot.xyz generates iPXE bootloaders and menus for 190+ operating systems using Ansible and Jinja2 templates. There is no application code in a traditional sense — the project produces `.ipxe` scripts and bootloader binaries.\n\n## Build Commands\n\n```bash\n# Syntax check (fast, run first)\nansible-playbook site.yml --syntax-check\n\n# Lint Ansible tasks\nansible-lint -v roles/netbootxyz/tasks\n\n# Full local build (generates menus + bootloaders to /var/www/html)\nansible-playbook site.yml\n\n# Menu-only build (skip bootloader compilation)\nansible-playbook site.yml -e \"generate_disks=false generate_checksums=false generate_signatures=false\"\n\n# Docker build (outputs to buildout/)\ndocker build -t localbuild --platform=linux/amd64 -f Dockerfile .\ndocker run --rm -it --platform=linux/amd64 -v $(pwd):/buildout localbuild\n\n# Release builds\n./script/build_release dev      # Development\n./script/build_release pr       # Pull request test\n./script/build_release rc       # Release candidate\n./script/build_release release  # Production\n./script/build_release rolling  # Rolling\n```\n\n### CI Checks (what PRs must pass)\n\n1. `ansible-playbook site.yml --syntax-check`\n2. `ansible-lint -v roles/netbootxyz/tasks`\n3. Full Docker build via `./script/build_release pr`\n\n### Testing\n\nMolecule tests exist but require Docker:\n```bash\npip install molecule molecule-docker\nmolecule test\n```\n\nThere are no unit tests. Validation is done through syntax checks, linting, and full builds.\n\n## Code Style\n\n### YAML / Ansible\n\n- Start every YAML file with `---` on line 1.\n- Use 2-space indentation consistently.\n- Use **fully-qualified collection names** (FQCN) for all modules:\n  - `ansible.builtin.template`, `ansible.builtin.set_fact`, `ansible.builtin.shell`, etc.\n  - Never use short names like `template:` or `shell:`.\n- Use `snake_case` for all variable names: `boot_domain`, `generate_menus`, `netbootxyz_root`.\n- Guard booleans with the `| default(true) | bool` pattern:\n  ```yaml\n  when:\n    - generate_menus | default(true) | bool\n  ```\n- Use `when:` as a list even for single conditions.\n- Use descriptive `name:` for every task.\n- The `.ansible-lint` config skips these rules (do not add workarounds for them):\n  - `command-instead-of-module`, `command-instead-of-shell`\n  - `no-changed-when`, `risky-shell-pipe`\n  - `literal-compare`, `var-naming[no-role-prefix]`\n\n### iPXE Templates (`.ipxe.j2` files)\n\n- Start with `#!ipxe` shebang on line 1.\n- Add a comment header with OS name and URL on lines 2-4.\n- iPXE scripts are **flat** — do not indent iPXE commands.\n- Use `#` for comments inside templates.\n- Variable conventions:\n  - iPXE runtime variables: `${variable_name}` (evaluated at boot time)\n  - Jinja2 template variables: `{{ variable }}` (evaluated at build time)\n  - These are often mixed: `${live_endpoint}{{ endpoints.foo.path }}`\n- Labels use `:label_name` in `snake_case`.\n- Navigation pattern: `goto ${menu} ||` at template start.\n- User selection: `choose <var> || goto <exit_label>`.\n- Exit pattern: clear menu and `exit 0`:\n  ```ipxe\n  :distro_exit\n  clear menu\n  exit 0\n  ```\n- Error pattern: echo, prompt, return to menu:\n  ```ipxe\n  :error\n  echo Error occurred, press any key to return to menu\n  prompt\n  goto main_menu\n  ```\n- Fallback chains: `command || goto fallback` for graceful degradation.\n- Architecture mapping varies by OS family:\n  - Red Hat: `x86_64` → `x86_64`, `arm64` → `aarch64`\n  - Debian: `x86_64` → `amd64`, `arm64` → `arm64`\n- Guard optional values: `isset ${variable}` in iPXE, `{% if value.field is defined %}` in Jinja2.\n\n### Jinja2 Patterns\n\n- Loop over releases: `{% for item in releases.<distro>.versions %}`\n- Sort by name: `{% for key, value in releases.items() | sort(attribute='1.name') %}`\n- Filter enabled items: `{% if value.enabled is defined and value.enabled | bool %}`\n- Template iteration uses `with_community.general.filetree` in tasks.\n\n### OS Definition Schema (`defaults/main.yml`)\n\n```yaml\nreleases:\n  distro_key:          # lowercase, no hyphens (e.g., almalinux, rockylinux)\n    name: \"Display Name\"\n    mirror: \"http://mirror.url\"\n    base_dir: \"path/on/mirror\"\n    enabled: true\n    menu: linux         # one of: linux, bsd, dos, unix\n    versions:\n      - code_name: \"version_id\"\n        name: \"Display Version\"\n```\n\nOptional fields: `archive_mirror`, `paths`, `flavors`, `platforms`, `version`.\n\n### Utility Definition Schema (`defaults/main.yml`)\n\n```yaml\nutilitiesefi:          # or utilitiespcbios64, utilitiespcbios32, utilitiesarm\n  utility_key:\n    name: \"Display Name\"\n    enabled: true\n    type: direct        # one of: direct, ipxemenu, memdisk, memtest, sanboot\n    kernel: \"<url>\"\n    initrd: \"<url>\"     # optional\n```\n\n## File Organization\n\n| Path | Purpose |\n|------|---------|\n| `site.yml` | Main playbook entry point |\n| `defaults/main.yml` | All OS/utility definitions and default config |\n| `endpoints.yml` | Live image endpoint URLs |\n| `user_overrides.yml` | Local overrides (not committed) |\n| `templates/menu/*.ipxe.j2` | ~100 iPXE menu templates |\n| `templates/disks/*.j2` | Bootloader embedded scripts |\n| `templates/pipxe/*.j2` | Raspberry Pi Makefile templates |\n| `tasks/*.yml` | 14 Ansible task files |\n| `vars/{debian,redhat,ubuntu}.yml` | Per-distro package lists |\n| `script/` | Build and release shell scripts |\n\n## Menu Hierarchy\n\n```\nmenu.ipxe (main) → linux.ipxe → ubuntu.ipxe, fedora.ipxe, ...\n                  → bsd.ipxe   → freebsd.ipxe, openbsd.ipxe, ...\n                  → live.ipxe  → live-ubuntu.ipxe, ...\n                  → utils-*.ipxe\n                  → windows.ipxe\n```\n\nMenus chain via `chain ${menu}.ipxe || goto error`. Signature verification gates chaining when `sigs_enabled` is true.\n\n## Error Handling\n\n- **Ansible**: Relies on default fail-fast behavior. No `block/rescue/always`. Guard tasks with `when:` conditions. Use `| default()` to prevent undefined variable errors.\n- **iPXE**: Use `command || goto fallback` chains. Protocol degradation: HTTPS → HTTP → local boot. Always provide a `:error` label that prompts the user.\n- **Shell scripts**: Use `set -e` at the top of all scripts.\n\n## Adding a New Operating System\n\n1. Add entry to `releases:` in `roles/netbootxyz/defaults/main.yml`.\n2. Create `roles/netbootxyz/templates/menu/<distro>.ipxe.j2` following existing templates.\n3. The menu template is auto-discovered via `filetree` iteration — no registration needed.\n4. Add the distro to the appropriate category menu (e.g., `linux.ipxe.j2`) if it needs a menu entry.\n5. If using live images, add endpoint to `endpoints.yml`.\n6. Test: `ansible-playbook site.yml --syntax-check && ansible-lint -v roles/netbootxyz/tasks`\n\n## Key Variables\n\n- **`boot_domain`**: Target domain for generated menus.\n- **`boot_version`**: Version string for releases.\n- **`site_name`**: Custom branding (defaults to `netboot.xyz`).\n- **`generate_menus` / `generate_disks`**: Enable/disable build components.\n- **`sigs_enabled`**: Enable signature verification for menu chaining.\n- **`live_endpoint`**: Base URL for live/rescue images.\n- **Runtime variables**: `${distro}_mirror` and `${distro}_base_dir` are auto-generated from `releases:` entries in `boot.cfg.j2` and available to all menu templates at boot time.\n\n## Git Workflow\n\n- **`development`**: Main development branch, default PR target.\n- **`RC`**: Release candidate staging.\n- **`master`**: Production releases.\n- Commit style: imperative mood, descriptive. Automated commits use `Version bump for ...` format.\n","category":"root","tokens":1897}]}