Skip to content

Hygiene gates that only report on a CI round-trip: local pre-flight discoverability #3522

Description

@kyle-sexton

Summary

Report, not a proposal. Filed at a maintainer's request from evidence gathered while landing #3503; I am deliberately not proposing a mechanism.

#3503 burned four separate CI rounds on gate findings. Every one was in prose or a test fixture rather than logic, and every one was found only by pushing and waiting. None changed the behavior under review.

The four findings, with the commit that fixed each

# Gate Finding Fixed in
1 plugin-options-docs-gate The guardrails README options table is generated from .claude-plugin/plugin.json userConfig. I hand-edited the README row, which passes markdownlint and fails the gate. a188792
2 hygiene / machine-specific-paths A realistic Windows user path in a test fixture (C:\Users\dev\AppData\Local\Temp\note.txt). The prescribed <user> placeholder then tripped shell-portability-lint, because \< is a GNU word boundary. Only forward slashes plus the placeholder satisfy both. a188792
3 hygiene / typos unparseable (the gate wants unparsable), twice, in prose written to explain an earlier fix. 55225d3
4 hygiene / machine-specific-paths /home/u/x.txt in a new regression fixture — a Linux user path. Fixed with /srv/app/notes.txt, which needs no user directory at all. pending

Findings 2 and 4 are the same gate catching the same class twice, on two different platforms' user-path shapes, several rounds apart.

What I actually tried locally

Stated as attempts, not assumptions.

Ran locally, and they work: scripts/check-shell-portability.sh, shellcheck -x, scripts/check-changelog-parity.sh (all three modes), scripts/sync-plugin-options-docs.py --check, markdownlint-cli2, scripts/affected-tests.sh --explain/--run, and typos (on PATH via WinGet; _typos.toml is in the repo root; a bare typos run over the repo exits 0).

Could not find a local entry point: machine-specific-paths. There is no script for it anywhere in this repo — find . -name '*machine-specific*' returns nothing. It lives in the external melodic-software/ci-workflows composite action, so the only way I know to exercise it is to push.

The honest shape of the problem

My first instinct was that these gates lack local runners. Checking rather than assuming, that is wrong for three of the four: sync-plugin-options-docs.py --check and typos were both runnable on this machine the whole time. I did not run them because I did not know they corresponded to those gate names.

So the gap is discoverability, not absence — with one genuine exception:

  1. There appears to be no single documented entry point that runs the hygiene gate set locally. An author must already know that plugin-options-docs-gate maps to sync-plugin-options-docs.py, and that the typos sub-step maps to a typos binary plus _typos.toml. Neither mapping is guessable from the failing check's name.
  2. machine-specific-paths genuinely has no in-repo runner, and it is the gate that fired twice.

A maintainer should confirm both points — I may still have missed an entry point, the same way I missed two.

Explicitly not proposed

Whether this becomes a pre-commit hook, a make/script target, a documented mapping table, or nothing at all is a repo-tooling decision. I am not proposing a mechanism and have not implemented anything.

Related

Surfaced while landing #3503. Sibling follow-ups from the same work: #3502, #3504.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions