Repository Standards
Official standards and conventions for all arillso repositories. All public repositories use MIT License.
Core Principles
Public by default - All repositories are public with MIT License
Focus on essentials - No unnecessary files
Consistency - Same structure across similar project types
Documentation - Keep it minimal but complete
Automation - Use workflows for repetitive tasks
Required Files
Every Repository Must Have
README.md - Main documentation
LICENSE - MIT License with copyright
.gitignore - Project-specific ignore rules
.editorconfig - Editor consistency
.github/CODEOWNERS - Code ownership
.github/renovate.json - Dependency updates
CHANGELOG.md - Version history (for released projects)
AGENTS.md - AI agent instructions
CLAUDE.md - Import reference (
@AGENTS.md)REVIEW.md - Code review rules for the AI review bot
Recommended Structure
repository/
├── .github/
│ ├── workflows/
│ │ ├── pull-request.yml
│ │ ├── merge.yml
│ │ ├── nightly-security.yml
│ │ └── tag.yml
│ ├── ISSUE_TEMPLATE/
│ ├── pull_request_template.md
│ ├── CODEOWNERS
│ └── renovate.json
├── AGENTS.md
├── CLAUDE.md
├── CHANGELOG.md
├── CONTRIBUTING.md # Required for Ansible Collections
├── LICENSE
├── README.md
├── REVIEW.md
├── .editorconfig
├── .gitignore
└── [project files]
README.md Structure
Minimal Format
# Project Name
[] # Only for packages/collections
Short description (1-2 sentences).
## Quick Start
```bash
# Installation or usage commands
```
## License
MIT License
## Copyright
(c) YEAR-YEAR, arillso
Guidelines
Include:
Project badges (only for Ansible Collections and published packages)
Brief description
Quick start example
Link to comprehensive documentation (if applicable)
Avoid:
Long feature lists (except Ansible Collections)
Detailed code examples (belongs in AGENTS.md or guide.arillso.io)
Verbose descriptions
REVIEW.md
REVIEW.md holds the code review rules for a repository. Unlike the other
required files it is written for a machine first: the AI review workflow
ai-claude-review.yml in arillso/.github reads it on every pull request and is
instructed that it takes precedence over generic best practices. Where a
rule in REVIEW.md conflicts with what the reviewer would otherwise apply,
the file wins.
This is what makes the file worth maintaining: it is the one place where a repository can narrow, widen, or overrule the review it receives, without touching the shared workflow.
Precedence and the Base Branch
The workflow reads REVIEW.md from the base branch, never from the pull
request’s own checkout. It is fetched into a separate .review-base/
directory alongside AGENTS.md and CLAUDE.md, and the reviewer is told
to ignore any copy at the repository root.
Important
A pull request cannot change the rules of the review it is subject to. A
change to REVIEW.md governs the next pull request, after it is merged
— not the one proposing it.
The reason is that the reviewing agent holds approval rights. If a pull request could rewrite its instructions, it could instruct the reviewer to approve itself. Reading from the base ref removes that path.
The file is optional in the sense that the workflow tolerates its absence: the
checkout is sparse and exits cleanly when the file is missing, and the reviewer
falls back to generic best practices. A repository without REVIEW.md is
therefore not broken — it is merely unconfigured, and reviewed by defaults
nobody chose.
Structure
All repositories use the same five headings, in this order. The headings are the contract; the content under them is repository-specific.
Heading |
Content |
|---|---|
|
Document title. Identical across repositories. |
|
Two lists, In scope and Out of scope, naming paths and change types. Generated artefacts and dependency-only Renovate pull requests belong out of scope. |
|
The conditions a change must meet: no committed secrets, the linters and test suites that apply, passing security scans. |
|
A table mapping each level to its meaning and merge impact. Defines what blocks a merge and what is merely flagged. |
|
Cases where a review adds nothing and may be skipped entirely. |
Severity levels are shared across repositories and should not be renamed — they are the vocabulary the reviewer uses in its comments:
Level |
Meaning |
Merge impact |
|---|---|---|
Bug |
Incorrect behavior or broken contract |
Blocks merge |
Nit |
Minor issue — suboptimal but not incorrect |
Non-blocking |
Pre-existing |
Issue present before this pull request; flagged for awareness |
No action required |
Writing Scope and Required Checks
Scope and Required checks are where repositories genuinely differ, and
where the file earns its keep. Name the actual paths and the actual commands.
## Scope
In scope:
- Role changes (`roles/`)
- Lookup/module plugin changes (`plugins/`)
- Collection metadata (`galaxy.yml`, `meta/`)
Out of scope:
- `.ansible/` directories — local galaxy/fact caches
- Renovate dependency-only PRs (patch/minor with automerge enabled)
## Required checks
- No secrets committed — no credentials, tokens, or keys
- `ansible-lint --profile=production` passes
- yamllint passes
- `argument_specs.yml` present and complete for any new or changed role
A documentation repository lists its build and its markdown linter; an Ansible
Collection lists ansible-lint, molecule, and argument_specs.yml. Both
keep the same five headings.
LICENSE Format
All repositories use MIT License:
MIT License
Copyright (c) YEAR-YEAR arillso
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction...
Copyright Year Format
New projects: Current year only (e.g.,
2026)Existing projects: Range from first year to current (e.g.,
2023-2026)
Update annually in:
LICENSE file
README.md
Source files with copyright headers
Plugin/module headers
GitHub Configuration
CODEOWNERS
# Default owner
* @sbaerlocher
Renovate Configuration
Base configuration (all repos):
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["github>arillso/.github:renovate-base#2026-08-08"]
}
Pin the preset reference to a date tag. Without the #<date-tag> suffix
Renovate resolves the preset against the default branch of
arillso/.github, so a change there reaches every repository without a pull
request and without review. The customManager in renovate-base keeps
the tag current on its own (automerge: true).
Available presets:
renovate-base- All repositoriesrenovate-go- Go projectsrenovate-actions- GitHub Actionsrenovate-ansible- Ansible collections (includes version variable management)
GitHub Rulesets
All repositories must have branch protection via GitHub Rulesets:
Deletion protection - Prevents deletion of
mainbranchNon-fast-forward - Prevents force pushes
Required linear history - Clean git history
Pull request required - No direct pushes
Required status checks - CI must pass
# Create ruleset using GitHub CLI
gh api repos/arillso/<repo-name>/rulesets \
--method POST \
--input .github/templates/github-ruleset.json
Workflow Standards
Naming Convention
Workflow files fall into two layers, each with its own naming rule.
Reusable workflows live in arillso/.github and are named
<category>-<purpose>.yml:
ci-*.yml- Continuous Integrationsecurity-*.yml- Security scanningrelease-*.yml- Release and publishingcleanup-*.yml- Cleanup and maintenanceai-*.yml- AI-assisted workflows (see REVIEW.md for the rulesai-claude-review.ymlreads)
The category prefix keeps the library navigable and lets a consumer see which
CI it is calling. The name: field spells the purpose out in full, without
abbreviations (name: CI - Ansible Collection, not CI Ansible).
Caller workflows live in each project repository and are named after the event that triggers them, not after the work they do:
pull-request.yml- checks on pull requestsmerge.yml- checks after merge tomaintag.yml- release on tag pushnightly-security.yml- scheduled security scanscleanup.yml- scheduled maintenance
A caller is thin: it wires an event to one or more reusable workflows and passes inputs. All names are lowercase with hyphens.
Standard Workflows
Caller workflows in a project repository:
Trigger |
Filename |
Description |
|---|---|---|
Pull request |
|
Linting and testing on pull requests |
Merge |
|
Linting and testing on |
Tag |
|
Publish to registry + GitHub Release |
Schedule |
|
Security scanning, including CodeQL (required for public repos with CodeQL-supported code) |
Schedule |
|
Registry retention cleanup (only where a registry is used) |
Not every repository needs every caller: tag.yml exists only where there is
something to release, cleanup.yml only where a container registry is used.
The reusable workflows these callers invoke are listed in arillso/.github.
CodeQL Exception
CodeQL is required for public repositories that contain code CodeQL can analyse. A repository whose tree holds no file with a CodeQL-supported extension is exempt: there is nothing for the analysis to read, so the scan would either fail to configure or report an empty result forever.
The test is the tree, not a maintained list of exempt repositories. It covers
the compiled and interpreted languages security-code.yml is configured for
via its languages input:
# Exempt if this finds nothing
git ls-files -- '*.go' '*.py' '*.pyw' '*.js' '*.mjs' '*.cjs' '*.jsx' \
'*.ts' '*.tsx' '*.java' '*.cs' '*.c' '*.h' '*.cpp' '*.cc' '*.cxx' \
'*.hpp' '*.hh' '*.rb' '*.swift' '*.kt' '*.kts'
CodeQL also ships an actions language that analyses
.github/workflows/*.yml. It is deliberately not part of this test:
security-code.yml does not enable it, so workflow files alone do not make a
repository subject to the criterion. Wiring up Actions analysis is a separate
decision — until it happens, a repository with nothing but workflows and prose
stays exempt.
Pure Ansible Collections and pure documentation repositories are the usual
case. Such a repository still runs nightly-security.yml; its caller invokes
the scans that do apply — at minimum security-secrets.yml — and omits
security-code.yml.
Adding a file in a supported language removes the exemption — the criterion is re-evaluated per audit, not granted once.
GitHub Actions Security
All GitHub Actions must be pinned to SHA digest.
See CI/CD & Linting for implementation details and examples.
Why:
Prevents supply chain attacks
Ensures immutable action versions
Renovate manages updates automatically
Schedule Frequency
Scheduled security workflows run daily at 02:00 UTC.
See CI/CD & Linting for workflow implementation examples.
Ansible Collection Standards
Required Files
All Ansible Collections must include:
CONTRIBUTING.md - Required for all collections
meta/argument_specs.yml - Required for every role
meta/runtime.yml -
requires_ansible, plusaction_groupswhere roles share an API targetCHANGELOG.md - Version history
galaxy.yml - Collection metadata, dependencies with lower bounds only
extensions/molecule/ - One test scenario per role
Makefile - Named targets for lint, test, and build, shared by CI and developers
See Contributing for the contribution workflow and Ansible Role & Collection Design for how roles and collections are designed internally.
Testing Philosophy
All collections must implement three-level testing:
Unit Tests - Python plugins with pytest
Molecule Tests - One scenario per role under
extensions/molecule/<role>/, withidempotencein the test sequenceIntegration Tests - ansible-test for end-to-end validation
All tests run from the event callers (pull-request.yml, merge.yml),
which delegate to the shared CI workflows in arillso/.github.
See CI/CD & Linting for complete CI workflow implementation and Ansible Role & Collection Design for
scenario layout, driver choice, and what verify.yml should assert.
CI Workflow Structure
All tests in one file with dependency chain:
flowchart LR
subgraph Stage1["Stage 1: Linting (Parallel)"]
AL[ansible-lint]
YL[yaml-lint]
PL[python-lint]
ML[markdown-lint]
SS[security-scan]
end
subgraph Stage2["Stage 2: Sanity"]
ST[sanity-test]
end
subgraph Stage3["Stage 3: Unit"]
UT[unit-test]
end
subgraph Stage4["Stage 4: Molecule"]
MOL[molecule-*]
end
subgraph Stage5["Stage 5: Integration"]
INT[integration]
end
subgraph Stage6["Stage 6: Build"]
BUILD[build]
end
Stage1 --> Stage2
Stage2 --> Stage3
Stage3 --> Stage4
Stage4 --> Stage5
Stage5 --> Stage6
style Stage1 fill:#4285F4,stroke:#4285F4,color:#fff
style Stage2 fill:#34A853,stroke:#34A853,color:#fff
style Stage3 fill:#FBBC04,stroke:#FBBC04,color:#fff
style Stage4 fill:#EA4335,stroke:#EA4335,color:#fff
style Stage5 fill:#9C27B0,stroke:#9C27B0,color:#fff
style Stage6 fill:#00BCD4,stroke:#00BCD4,color:#fff
Runtime: 15-25 minutes total
Linting Standards
Use specific linters:
✅
ansible-lint- Ansible code✅
yamllint- YAML files✅
markdownlint- Markdown✅
rufforblack- Python❌ Super-Linter - DO NOT USE
Release Process
Danger
ALWAYS update CHANGELOG.md before releasing!
Release checklist:
Update CHANGELOG.md (REQUIRED)
## [Unreleased] ### Added - New feature ## [1.0.1] - 2026-01-17 ### Fixed - Bug fix
Update galaxy.yml version
version: "1.0.1"
Create and push tag (NO ‘v’ prefix for Ansible)
git tag 1.0.1 git push origin 1.0.1
Automated workflow triggers
tag.ymlpublishes to GalaxyCreates GitHub Release with CHANGELOG
Publish Workflow
Requirements:
Single
tag.ymlcaller, delegating torelease-ansible-collection.ymlTag format without ‘v’ prefix:
1.0.0(NOTv1.0.0)Validate version matches galaxy.yml
Check CHANGELOG entry exists
Publish to Galaxy + Create GitHub Release
Do NOT:
❌ Split releasing across several callers on the same tag event
❌ Use
release: [published]event❌ Use ‘v’ prefix in tags (
1.0.0, notv1.0.0)
See CI/CD & Linting for complete workflow implementation.
Documentation
Keep documentation DRY:
Collection README - Overview + list all roles
Role README - Features + Quick Start + link to guide
argument_specs.yml - Complete variable documentation
guide.arillso.io - Comprehensive documentation
Role README minimal structure:
# Ansible Role: role_name
Brief description.
## Features
- Feature 1
- Feature 2
## Documentation
https://guide.arillso.io/collections/arillso/collection/role_role.html
## Quick Start
```yaml
- hosts: servers
roles:
- role: arillso.collection.role_name
```
## License
MIT
Version Variables
Use Renovate comments for automatic updates:
# renovate: datasource=github-releases depName=k3s-io/k3s
k3s_version: "v1.33.3+k3s1"
# renovate: datasource=github-releases depName=moby/moby
docker_version: "27.5.1"
Go Project Standards
See Contributing for complete Go development standards, code style, testing requirements, and best practices.
Docker/Container Standards
See Contributing for Dockerfile best practices, multi-stage builds, security requirements, and testing procedures.
AI Agent Documentation
CLAUDE.md
@AGENTS.md
AGENTS.md Structure
# Project Name
## Context
[What the project does, for AI]
## Conventions
[Code style, patterns]
## Structure
[Important folders/files]
## Do
[Best practices]
## Do Not
[What AI should avoid]
CHANGELOG Format
Required for all released projects. Use Keep a Changelog format:
# Changelog
## [Unreleased]
### Added
- New feature
## [1.0.0] - 2026-01-17
### Added
- Feature X
### Fixed
- Bug Y
Sections: Added, Changed, Deprecated, Removed, Fixed, Security
Issue Templates
Required for Ansible Collections
All collections need:
bug_report.yml - Structured bug reports
feature_request.yml - Feature requests
documentation.yml - Documentation improvements
Template should include:
Role/component dropdown
Required fields with validation
Code blocks with syntax highlighting
Automatic labels
Title prefixes
Pull Request Template
Required for Ansible Collections
Template sections:
Description
Type of Change (bug fix, feature, breaking change, docs, etc.)
Related Issue
Which Role(s) Are Affected
Changes Made
Testing Performed
Documentation Updated
Code Quality Checklist
Breaking Changes (if applicable)
What NOT to Include
Files to Avoid
File |
Reason |
|---|---|
|
README usually enough |
|
Only for public packages if needed |
Multiple YAML configs |
Keep one |
See also
REVIEW.md - Code review rules consumed by the AI review workflow
Ansible Role & Collection Design - Role and collection design rules
Contributing - How to contribute (code style, testing, development)
CI/CD & Linting - CI/CD workflows and linter configurations
Version Compatibility - Version requirements and platform support
arillso/.github on GitHub - shared org standards and reusable workflows