Name script/check as the gate repo-type verifications belong in #50

Closed
clawbot wants to merge 1 commits from policy/name-the-gate-for-repo-type-checks into main
Collaborator

SPECULATIVE and ahead of your ruling. One sentence of policy prose changed; no script, config or checklist is touched, and closing it costs nothing.

What the rule says now

prompts/REPO_POLICIES.md line 72:

> Repo-type-specific pre-commit extras (e.g. go mod tidy verification in Go repos) belong in script/precommit, not in the hook itself.

The second half of that is right and stays: the git hook file is a shim, and the logic lives in script/. The first half names the wrong script.

script/precommit is one caller of script/check, not a gate. A verification placed there alone runs for a contributor who installed the hook and committed through it, and for nobody else: script/check does not run it, and CI runs script/cibuild (docker build .), which does not either. So the rule as written directs repo-type verifications to the single place in the entrypoint set where CI cannot see them, while script/check — which the Dockerfile build step runs, and which script/precommit itself calls — is the place where one run covers every path.

This is not a homoicon-specific observation, which is why it is filed here rather than patched into a vendored copy: the shape holds for every repo that adopts the scripts, because it follows from the entrypoint graph the policy itself defines (script/check runs test/lint/fmt-check; script/precommit calls script/check; the Dockerfile runs make check; the workflow runs script/cibuild).

The change

  Repo-type-specific verifications (e.g. `go mod tidy` verification in Go repos)
  belong in `script/check`, which is the gate the other entrypoints funnel
  through: it runs in the Dockerfile build step and therefore in CI, and
  `script/precommit` inherits it by calling `script/check`. In
  `script/precommit` alone such a check binds only the contributors who
  installed the hook, and the hook file itself stays a shim that carries no
  checks of its own. Anything added to `script/check` must be read-only, since
  `make check` must not modify files, so use a verify or diff mode
  (`go mod tidy -diff`) rather than a command that rewrites the tree.

The read-only clause is there because the placement implies a constraint that has already caught one implementation out: make check must not modify files (line 238 of this document), and the obvious way to verify tidiness — run go mod tidy, then git diff — violates that. Naming the gate without naming the constraint moves a file-rewriting command into a script that must not rewrite files.

The alternative, and why not it

Option A (this PR): amend the text so it names the gate. The rule then matches what the entrypoint graph already makes true, and adopting repos get the check on every path including CI.

Option B: keep the text and move the gate back to script/precommit. Rejected. It restores the exact defect — a rule enforced only by an optional local hook, invisible to CI — which is the failure mode several units in the consuming repos have spent effort closing. It would also mean the check is not run by make check, so a contributor cannot verify locally what CI will judge them on. The only thing Option B buys is not editing this file, and it buys that by keeping a gate that reports success without having checked.

There is no third option that keeps both halves: script/precommit cannot be reached by CI without CI running the pre-commit hook, which is not what the workflow does.

Provenance and current state, stated plainly

  • The question comes from sneak/homoicon#349, which was raised by the review of sneak/homoicon#340.
  • That PR is open and unmerged (needs-rework as of this writing), so in homoicon today the tidy check still lives in script/precommit exactly as the current text says. The drift this fixes is prospective there, not landed. The argument for naming the gate does not depend on that PR: it holds for any repo, because script/precommit is off the CI path by construction.
  • homoicon's vendored REPO_POLICIES.md is byte-identical to this repo's canonical file on main (sha256 bcf11c312a1bee18a0e937eb412b51914411c1ab23308b8362409f3f88379ff7, 416 lines, diff clean), which is why the change is proposed here and nothing is edited downstream. Re-vendoring waits until this lands.

Scope of the sweep

Grepped every *.md, the Makefile and the Dockerfile in this repo for go mod tidy and for precommit:

  • prompts/REPO_POLICIES.md:72 — the sentence changed here, the only statement of where such a check belongs.
  • prompts/REPO_POLICIES.md:366 — "Always run go mod tidy before committing": an instruction to the author, not a gate location. Unaffected and not contradicted.
  • prompts/CODE_STYLEGUIDE_GO.md:462go mod tidy in a getting-started walkthrough. Unaffected.
  • prompts/REPO_POLICIES.md:65-66, 180-184, prompts/EXISTING_REPO_CHECKLIST.md:57, prompts/NEW_REPO_CHECKLIST.md:95-98, README.md:129-134 — all state only that script/precommit is what the hook runs and that it calls script/check. Still true, unchanged, and consistent with the new wording.

Nothing else in the repo states either version of the rule, so nothing is left saying the other one.

The repo-root REPO_POLICIES.md is a symlink to prompts/REPO_POLICIES.md, so the single edit covers both paths.

Note on the next branch

next (six commits ahead of main, milestone PR #34) carries the same sentence, at its line 76, with different surrounding text. This PR is cut from main, matching #49 and this repo's TODO.md workflow. The hunks do not overlap the ones next changes, so a later next merge should carry this sentence through; if you would rather have it on next instead, say so and I will re-cut it there.

Verification

script/cibuild (docker build ., which runs make check inside the image), exit 0. The check layer executed rather than being served from cache: #11 ... DONE 3.1s, with All matched files use Prettier code style! from both script/lint and script/fmt-check in the log. make fmt produced no further changes, so the new wording was already prettier-clean at 80 columns with 4-space tabs. The one dangling image the build produced was removed by id; docker ps -a is empty. No prune of any kind was run.

last_modified in the front matter updated to 2026-08-20, per this file's own rule.

SPECULATIVE and ahead of your ruling. One sentence of policy prose changed; no script, config or checklist is touched, and closing it costs nothing. ## What the rule says now `prompts/REPO_POLICIES.md` line 72: > Repo-type-specific pre-commit extras (e.g. `go mod tidy` verification in Go repos) belong in `script/precommit`, not in the hook itself. The second half of that is right and stays: the git hook file is a shim, and the logic lives in `script/`. The first half names the wrong script. `script/precommit` is one caller of `script/check`, not a gate. A verification placed there alone runs for a contributor who installed the hook and committed through it, and for nobody else: `script/check` does not run it, and CI runs `script/cibuild` (`docker build .`), which does not either. So the rule as written directs repo-type verifications to the single place in the entrypoint set where CI cannot see them, while `script/check` — which the Dockerfile build step runs, and which `script/precommit` itself calls — is the place where one run covers every path. This is not a homoicon-specific observation, which is why it is filed here rather than patched into a vendored copy: the shape holds for every repo that adopts the scripts, because it follows from the entrypoint graph the policy itself defines (`script/check` runs `test`/`lint`/`fmt-check`; `script/precommit` calls `script/check`; the Dockerfile runs `make check`; the workflow runs `script/cibuild`). ## The change ``` Repo-type-specific verifications (e.g. `go mod tidy` verification in Go repos) belong in `script/check`, which is the gate the other entrypoints funnel through: it runs in the Dockerfile build step and therefore in CI, and `script/precommit` inherits it by calling `script/check`. In `script/precommit` alone such a check binds only the contributors who installed the hook, and the hook file itself stays a shim that carries no checks of its own. Anything added to `script/check` must be read-only, since `make check` must not modify files, so use a verify or diff mode (`go mod tidy -diff`) rather than a command that rewrites the tree. ``` The read-only clause is there because the placement implies a constraint that has already caught one implementation out: `make check` must not modify files (line 238 of this document), and the obvious way to verify tidiness — run `go mod tidy`, then `git diff` — violates that. Naming the gate without naming the constraint moves a file-rewriting command into a script that must not rewrite files. ## The alternative, and why not it **Option A (this PR): amend the text so it names the gate.** The rule then matches what the entrypoint graph already makes true, and adopting repos get the check on every path including CI. **Option B: keep the text and move the gate back to `script/precommit`.** Rejected. It restores the exact defect — a rule enforced only by an optional local hook, invisible to CI — which is the failure mode several units in the consuming repos have spent effort closing. It would also mean the check is not run by `make check`, so a contributor cannot verify locally what CI will judge them on. The only thing Option B buys is not editing this file, and it buys that by keeping a gate that reports success without having checked. There is no third option that keeps both halves: `script/precommit` cannot be reached by CI without CI running the pre-commit hook, which is not what the workflow does. ## Provenance and current state, stated plainly - The question comes from https://git.eeqj.de/sneak/homoicon/issues/349, which was raised by the review of https://git.eeqj.de/sneak/homoicon/pulls/340. - That PR is **open and unmerged** (`needs-rework` as of this writing), so in homoicon today the tidy check still lives in `script/precommit` exactly as the current text says. The drift this fixes is prospective there, not landed. The argument for naming the gate does not depend on that PR: it holds for any repo, because `script/precommit` is off the CI path by construction. - homoicon's vendored `REPO_POLICIES.md` is byte-identical to this repo's canonical file on `main` (sha256 `bcf11c312a1bee18a0e937eb412b51914411c1ab23308b8362409f3f88379ff7`, 416 lines, `diff` clean), which is why the change is proposed here and nothing is edited downstream. Re-vendoring waits until this lands. ## Scope of the sweep Grepped every `*.md`, the `Makefile` and the `Dockerfile` in this repo for `go mod tidy` and for `precommit`: - `prompts/REPO_POLICIES.md:72` — the sentence changed here, the only statement of where such a check belongs. - `prompts/REPO_POLICIES.md:366` — "Always run `go mod tidy` before committing": an instruction to the author, not a gate location. Unaffected and not contradicted. - `prompts/CODE_STYLEGUIDE_GO.md:462` — `go mod tidy` in a getting-started walkthrough. Unaffected. - `prompts/REPO_POLICIES.md:65-66, 180-184`, `prompts/EXISTING_REPO_CHECKLIST.md:57`, `prompts/NEW_REPO_CHECKLIST.md:95-98`, `README.md:129-134` — all state only that `script/precommit` is what the hook runs and that it calls `script/check`. Still true, unchanged, and consistent with the new wording. Nothing else in the repo states either version of the rule, so nothing is left saying the other one. The repo-root `REPO_POLICIES.md` is a symlink to `prompts/REPO_POLICIES.md`, so the single edit covers both paths. ## Note on the `next` branch `next` (six commits ahead of `main`, milestone PR https://git.eeqj.de/sneak/prompts/pulls/34) carries the same sentence, at its line 76, with different surrounding text. This PR is cut from `main`, matching https://git.eeqj.de/sneak/prompts/pulls/49 and this repo's `TODO.md` workflow. The hunks do not overlap the ones `next` changes, so a later `next` merge should carry this sentence through; if you would rather have it on `next` instead, say so and I will re-cut it there. ## Verification `script/cibuild` (`docker build .`, which runs `make check` inside the image), exit 0. The check layer executed rather than being served from cache: `#11 ... DONE 3.1s`, with `All matched files use Prettier code style!` from both `script/lint` and `script/fmt-check` in the log. `make fmt` produced no further changes, so the new wording was already prettier-clean at 80 columns with 4-space tabs. The one dangling image the build produced was removed by id; `docker ps -a` is empty. No prune of any kind was run. `last_modified` in the front matter updated to 2026-08-20, per this file's own rule.
clawbot added 1 commit 2026-08-20 05:07:48 +02:00
policy: name script/check as the gate repo-type verifications belong in
All checks were successful
check / check (push) Successful in 16s
d0668adc09
The rule put repo-type-specific extras such as `go mod tidy`
verification in `script/precommit`. `script/precommit` is one caller of
`script/check`, not the gate: a check placed there alone runs only for
contributors who installed the hook, and never in CI. Naming
`script/check` instead puts the check on every path that already funnels
through it, including the Dockerfile build step and therefore CI, with
the pre-commit hook inheriting it.

Records the read-only constraint that placement implies, since
`make check` must not modify files.
sneak closed this pull request 2026-08-30 06:27:43 +02:00
All checks were successful
check / check (push) Successful in 16s
Required
Details

Pull request closed

Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/prompts#50