--- title: "Development Notes" html_title: "Enroll Development Notes" description: "Developer-oriented overview of Enroll architecture, collectors, safety helpers, renderers, and tests." ---
Development notes

How the codebase is structured

A compact web version of the current development guide for contributors and reviewers.

Runtime flow

The CLI injects INI defaults, parses arguments, performs root PATH safety checks, then dispatches to harvest, manifest, diff, explain, or validate. Manifest and diff normalize directory/tar/SOPS inputs into private frozen working trees before consuming artifacts.

Harvest order

Platform detection and package indexing run first. Collectors then process runtime state, cron/logrotate, services/packages, users plus Flatpak/Snap, container images, package-manager config, remaining /etc, /usr/local, and extra paths. Parent directories and package inventory are appended before writing state.json.

Global de-duplication

captured_global keeps a destination path from being owned by two generated roles. New collectors should route file/link capture through the shared helpers rather than appending directly to snapshots.

Backends

DpkgBackend and RpmBackend implement ownership lookup, manual package listing, installed inventory, /etc indexing, modified config detection, and package-manager config exclusions. Add new backends behind platform.get_backend().

Renderer-neutral model

Harvest snapshots are converted into CMModule objects before Ansible rendering. Common role grouping can combine package and systemd modules by Debian Section/RPM Group unless --no-common-roles or --fqdn is used.

Ansible renderer

The renderer writes scaffold, tasks, handlers, files/templates, variables, playbooks, inventory, requirements, and a generated README. It keeps harvested free text in data variables and only interpolates sanitized role/module tokens into task structure.

Collector map

CollectorPurposeTypical roles/snapshots
RuntimeStateCollectorRoot-only runtime sysctl and firewall fallback snapshots.sysctl, firewall_runtime, enroll_runtime
CronLogrotateCollectorCentralises cron and logrotate before package/service roles claim files.cron, logrotate
ServicePackageCollectorEnabled systemd services, related packages, config, drop-ins, env files, and enablement symlinks.service and package roles
UsersCollectorNon-system users, authorized keys, safe SSH material, shell dotfiles in dangerous mode, Flatpak/Snap discovery.users, flatpak, snap
ContainerImagesCollectorDocker/Podman image metadata, digest-pinned pull references, tag aliases, notes for non-reproducible local tags.container_images
PackageManagerConfigCollectorAPT/DNF/YUM repo and keyring configuration.apt_config, dnf_config
UsrLocalCustomCollector/usr/local/etc and executable scripts under /usr/local/bin.usr_local_custom
ExtraPathsCollectorUser requested include/exclude path capture.extra_paths

Testing focus

The test suite covers CLI parsing and config injection, package backends, collectors, path filtering, secret detection, filesystem safety, SOPS helpers, remote extraction, manifest rendering, JinjaTurtle integration, validation, diff formatting, and output hardening. New features should usually add focused unit tests plus an end-to-end render or validation check where generated Ansible changes.