Architecture specification

Linter Configuration

A single .linter/ directory holds the repository’s own lint configuration and overrides, layered over organisation defaults from the environment.

Applies at
.linter/
Status
Stable
Source · managed
.linter/README.md

01 Defines

The standard location for repository-owned linter configuration: one file per tool, kept out of the repository root and loaded by path from the development container and CI.

02 Applies when

  • A repository needs to override or extend the organisation’s default lint rules.
  • Several linters each want their own configuration file.
  • The same configuration has to apply locally, in the dev container, and in CI.

03 Boundaries

  • Organisation defaults come from the devcontainer and CI/CD tooling, not from this directory.
  • The directory holds configuration, not the command that runs the linters.
  • A tool that insists on a root-level file gets a symlink or minimal shim, not a second copy.

Expected behaviour

  1. 01
    Repository-specific lint configuration lives in .linter/ rather than at the root.
  2. 02
    Tools are pointed at these files with environment variables or explicit configuration paths.
  3. 03
    Files contain overrides and repository-specific settings, not a restatement of the defaults.
  4. 04
    The repository exposes one aggregate lint command that uses this configuration.

Behaviour#

Linters conventionally scatter dotfiles across the repository root. Here they are gathered into one directory, so the root stays focused on the repository’s own structure and the lint setup is visible in one place.

Configuration is layered. The organisation’s defaults travel with the Development Container and the CI/CD tooling; files in .linter/ contain only what this repository changes. Each tool is told where to find its file — --config .linter/.markdownlint.json, -config-file .linter/actionlint.yaml — instead of discovering it at the root.

  • .linter/
  • .markdownlint.json Markdown rule overrides
  • .shellcheckrc Optional checks enabled; runtime-sourced files allowed
  • .hadolint.yaml Ignored Dockerfile rules, each with a reason
  • .tflint.hcl Built-in Terraform ruleset, recommended preset
  • .yamllint.yml Validity only; Prettier owns YAML formatting
  • .prettierrc.json Formatting preferences
  • actionlint.yaml Known self-hosted runner labels
  • editorconfig-checker.json Generated and vendored paths excluded
  • .gitleaks.toml Secret-scanning allowlist
  • trivy.yaml Skipped directories, scanners, severities
  • .checkov.yml IaC scan skip paths
  • lychee.toml Link-check base URL and exclusions
  • ignore Shared ignore patterns for generated output
  • .mega-linter.yml Managed MegaLinter settings

One aggregate command#

The directory says how each linter is configured; it deliberately does not say how they are run. The repository exposes a single aggregate lint capability so that nobody needs to know the individual tools or their flags. In this repository that is make lint, the Lint Gate .

The ignore file is also a repository contract in its own right: the Environment Doctor checks that .linter/ignore exists.

Examples#

Overrides are small and say why they exist:

.linter/.hadolint.yaml
ignored:
  - DL3008 # Pin versions in apt-get install (pinned by base image).
  - DL3059 # Multiple consecutive RUN instructions (readability).
.linter/.yamllint.yml (excerpt)
# yamllint — validity checks only. Prettier owns YAML formatting.
---
extends: default

rules:
  key-duplicates: enable
  line-length: disable
  indentation: disable

The second example shows layering between tools as well as over defaults: one tool is narrowed to what another does not already cover.