docs(CLAUDE.md): name the lint command that works in the CI sandbox - #1126
Conversation
tend-agent
left a comment
There was a problem hiding this comment.
Verified the premise from inside the sandbox on this run: command -v pre-commit is empty as tend-sandbox, and uv tool run pre-commit run --all-files completes with all 13 hooks green on this branch. The paragraph is accurate and the placement is right. Two things it leaves on the table.
The Commands block still hands out the failing form. Line 29 is unchanged:
pre-commit run --all-files # lint: ruff, typos, actionlint, shellcheck, uv-lock
That block is the copy-paste source — it is what a session reads when it wants the lint command, and the new paragraph sits eleven lines below it, outside the fence. So the exact failure this PR documents is still one skim away. uv tool run pre-commit run --all-files is correct for a human checkout too (uv is already the prerequisite for uv run pytest two lines up), so the block can carry the one form that works everywhere rather than a form that works for one reader and a footnote for the other. That also collapses the two copies of the hook list — line 29's comment and the new sentence — into one, which is worth something given they already disagree (see below). Outside the diff, so I can't suggest it inline; happy to push it if you'd rather not hand-edit.
The substitute-cost list is the sentence's whole job, and it undercounts. .pre-commit-config.yaml defines 13 hooks; ruff-plus-shellcheck skips ten of them, including all three repo: local guards. Those are the ones a substitute can't approximate, and the config's own comments say why they exist: no-preprocessor-poison-in-skills guards a sequence that "crashes the session before any assistant turn runs" and has regressed twice, and sandbox-env-reserved-parity guards what the comment calls "the actual security boundary". A session weighing whether a narrower gate is good enough, reading only "typos, actionlint and uv-lock", can reasonably decide yes. Naming the local guards is what makes the sentence deter. Inline suggestion on the line.
Minor: .claude/skills/release/SKILL.md carries the same bare form — "Then wt test and pre-commit run --all-files." That one is normally maintainer-driven where pre-commit is on PATH, so it may not be worth touching; flagging it since it is the same pattern.
Holding off on approving — self-authored.
Move the Commands block onto `uv tool run pre-commit run --all-files` so the copy-paste source carries the form that works in both a human checkout and the CI sandbox, and name the three `repo: local` guards a ruff-plus-shellcheck substitute misses. Same prefix in the release skill's lint step.
|
Both points taken, pushed as 34bc105. Commands block. Line 29 now reads Substitute cost. Inline suggestion applied, reworded only where it overlapped the block above. Verified rather than counted from the config: the full run prints 13 hook lines, of which ruff-check, ruff-format and shellcheck are what a ruff-plus-shellcheck substitute covers. The release skill. Took it — same four-word prefix, and the form works for the maintainer-driven case too, so there's no reader left needing the bare one. That was the argument for changing the Commands block; it applies equally here. Verification
|
pre-commitis not on the CI sandbox's PATH, but CLAUDE.md's Commands block names barepre-commit run --all-filesas the lint gate — so a tend session that follows it getscommand not found. Three sessions hit that in the last 24 h; two recovered withuv tool run pre-commit, one substituted ruff plus shellcheck and ran a narrower gate than the repo's. The Commands block now carriesuv tool run pre-commit run --all-files— the one form that works in both a human checkout and the sandbox — and the paragraph below it says why the prefix is there and what a narrower substitute costs: ten of the thirteen hooks, including the threerepo: localguards..claude/skills/release/SKILL.md's lint step takes the same prefix.Evidence, verification, and the alternative I didn't take
Verified live from inside the sandbox (this run, as
tend-sandbox):command -v pre-commitis empty;command -v uvis/opt/hostedtoolcache/uv/0.12.8/x86_64/uv;uv tool run pre-commit --versionprintspre-commit 4.6.2.Occurrences in the window
2026-08-31T07:50:43Z → 2026-09-01T07:49Z, from the session JSONL of each run:tend-mention(#1121)pre-commit run --all-files→/usr/bin/bash: line 1: pre-commit: command not found, then retried asuv tool run pre-committend-mention(#1121)command not found, same recovery; its summary notes "viauv tool run—pre-commitisn't on PATH in this sandbox"tend-review(#1124)command not found, no retry — substituteduv run ruff check+ruff format --checkand a standalone shellcheck, sotypos,actionlintanduv-lockwent unrunThree further sessions (33424356768, 33440961515, 33442043938) plus
tend-nightly33478582882 went straight touv tool run pre-commitwithout trying the bare form — the workaround is already in circulation, just not written down. The overlay's own weekly recipe already usesuv tool run pre-commit autoupdateat.claude/skills/running-tend/SKILL.md:196.Classification. Structural — the same conditions produce the same failure every session. Cost class: waste this window; no wrong outward action occurred. Run 33479300709 did not claim
pre-commitpassed (its review said "shellcheck clean on the script", which is accurate), so nothing false was posted. The remedy is one paragraph in a file that already exists, which is why it clears Gate 3 despite the waste class.The alternative, and why not.
sandbox_setup: ["uv tool install pre-commit"]in.config/tend.yamlwould put the binary on the sandbox PATH, which is the shape #691 was steered toward ("should we install into our environment in the workflow, rather than having the agent do it?"). It's repo-level, so it would run on every agent boot — including the ~11tend-notificationssessions a day that never lint — to spare a four-word prefix on the few that do. That trade reads the wrong way against "Simplicity outranks efficiency", so I've left the knob to you rather than taking it.Verification of this change:
uv tool run pre-commit run --files CLAUDE.mdpasses (typos,ruff format, the plugin-skill and install-tend sync hooks all green);uv run pytestis 882 passed.