Parallel to #531 (zizmor), same defect, same fix shape. Filed after surveying every hook in ~/.config/pre-commit/config.yaml.
Problem
~/.config/pre-commit/config.yaml:91-97:
- id: yamllint
name: "YAML Lint (yamllint)"
entry: yamllint
language: system
types: [yaml]
pass_filenames: true
Bare entry: yamllint, no --config. yamllint falls back to its own discovery — a repo-root .yamllint*, else $XDG_CONFIG_HOME/yamllint/config, else its built-in default preset.
CI does not do this. standards/run-standards.sh:146-150:
cfg=""
for c in .yamllint .yamllint.yml .yamllint.yaml; do
if [[ -f "${repo}/${c}" ]]; then cfg="${repo}/${c}"; break; fi
done
[[ -n "${cfg}" ]] || cfg="${config_dir}/yamllint.yml"
Repo config wins, else the canonical github-workflows/standards/yamllint.yml. So for any repo without its own .yamllint*, pre-commit and CI lint the same file against different rules.
Why it matters
Same class as #531: a local gate that disagrees with CI is not a gate. It fails in both directions — a local pass that CI rejects (wasted push, which Protocol 4 exists to prevent), or a local block on a rule CI does not enforce (which trains SKIP=yamllint as a habit).
Lower severity than #531 in one respect: yamllint's built-in default is stricter than the canonical config on line length, so the common failure is a false block rather than a missed finding. Still wrong, and the fix is identical.
Fix
Per the option-2 decision on #531: github-workflows stays canonical, dotfiles vendors standards/yamllint.yml to a stable local path at install time, and this hook passes it as the fallback when the repo has no config of its own.
Do not copy markdownlint's either/or branch — see #532 for why that shape is itself buggy.
Related: #531 (zizmor, same fix), #532 (markdownlint, the bug not to reproduce), smartwatermelon/dev-env#77.
https://claude.ai/code/session_014Xei4nFGe48rE4vryi64Yx
Parallel to #531 (zizmor), same defect, same fix shape. Filed after surveying every hook in
~/.config/pre-commit/config.yaml.Problem
~/.config/pre-commit/config.yaml:91-97:Bare
entry: yamllint, no--config. yamllint falls back to its own discovery — a repo-root.yamllint*, else$XDG_CONFIG_HOME/yamllint/config, else its built-indefaultpreset.CI does not do this.
standards/run-standards.sh:146-150:Repo config wins, else the canonical
github-workflows/standards/yamllint.yml. So for any repo without its own.yamllint*, pre-commit and CI lint the same file against different rules.Why it matters
Same class as #531: a local gate that disagrees with CI is not a gate. It fails in both directions — a local pass that CI rejects (wasted push, which Protocol 4 exists to prevent), or a local block on a rule CI does not enforce (which trains
SKIP=yamllintas a habit).Lower severity than #531 in one respect: yamllint's built-in default is stricter than the canonical config on line length, so the common failure is a false block rather than a missed finding. Still wrong, and the fix is identical.
Fix
Per the option-2 decision on #531:
github-workflowsstays canonical, dotfiles vendorsstandards/yamllint.ymlto a stable local path at install time, and this hook passes it as the fallback when the repo has no config of its own.Do not copy markdownlint's either/or branch — see #532 for why that shape is itself buggy.
Related: #531 (zizmor, same fix), #532 (markdownlint, the bug not to reproduce), smartwatermelon/dev-env#77.
https://claude.ai/code/session_014Xei4nFGe48rE4vryi64Yx