Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .markdownlint-cli2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@ globs:
ignores:
- node_modules/**
- .venv/**
# Other Claude Code sessions' git worktrees, for the reason spelled out in
# .yamllint.yaml. `**/*.md` matches dot directories here, so a second
# checkout doubles the file count — measured at 114 files against 57 tracked.
# It has passed so far only because a worktree holds a copy of this
# repository's own markdown; a branch under review with one lint error in it
# would fail `make validate` on main, pointing at a file main does not have.
- .claude/worktrees/**
18 changes: 18 additions & 0 deletions .yamllint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,24 @@ ignore: |
stacks/observability/snmp-exporter/.rendered/
node_modules/
.venv/
# Other Claude Code sessions' git worktrees. Each one is a whole second
# checkout, so without this yamllint lints another branch's copy of every
# file here — including the ciphertext the entries above exist to exempt.
# Those patterns contain a slash, which anchors them to the repository root
# the way .gitignore does, so `secrets/*.sops.yaml` does not match
# `.claude/worktrees/<branch>/secrets/observability.sops.yaml`. Measured: 23
# findings, none of them in this tree.
#
# It is a LOCAL false red and CI never reproduces it, which is the worst
# shape for a check to have: `make validate` fails on the deploy host for a
# clean change, and an operator who learns to dismiss that has stopped
# reading the one command that gates a deploy.
#
# This list has to be maintained by hand because yamllint does not read
# .gitignore. editorconfig-checker is immune to the same problem for a
# structural reason — scripts/lint.sh hands it a `git ls-files` list rather
# than letting it walk the tree. See the comment there.
.claude/worktrees/

rules:
line-length:
Expand Down
26 changes: 26 additions & 0 deletions scripts/lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,32 @@
# linter it cannot reach, CI may not, because a linter skipped there is one
# nobody will ever run.
#
# WHAT EACH LINTER LOOKS AT, AND WHY THAT IS NOT OBVIOUS
#
# Three of these decide their own file list, and none of them reads .gitignore.
# That only matters because a workstation has trees a CI checkout does not —
# rendered config, certificates, backups, and another session's git worktree
# under .claude/worktrees/, which is an entire second copy of this repository.
# A linter that walks the tree finds all of it and fails locally for a change
# that is clean, while CI stays green. Green where nothing runs and red where
# everything does is the wrong way round, and it is how a check stops being
# read.
#
# So, measured rather than assumed:
#
# - yamllint walks `.`, so its exclusions live in .yamllint.yaml
# - markdownlint-cli2 globs `**/*.md`, which DOES match dot directories, so
# its exclusions live in .markdownlint-cli2.yaml
# - shellcheck is handed scripts/*.sh below — one literal glob, cannot wander
# - actionlint reads only <repo root>/.github/workflows. Verified with
# -verbose: it lints 2 files with a worktree present, not 4
# - editorconfig-checker is handed a `git ls-files` list built below, so it
# sees tracked files and nothing else
#
# The last of those is the shape to copy when this comes up again: a list built
# from git cannot drift, whereas the first two carry a list of exclusions that
# has to be extended by hand every time a new ignored directory appears.
#
# --skips-file follows seed-validation-env.sh's contract: the caller owns the
# path and its lifetime. scripts/validate.sh passes an mktemp it removes on exit
# and adds the line count to its SKIPPED counter. Without it a skip here would
Expand Down