Repository navigation
triage template feedback: worktree-safe checks, settled ARG002, example lifecycle - #111
Merged
Merged
Conversation
Claude Code creates git worktrees under .claude/worktrees/, which puts a complete second checkout inside the repository. Both checks that walk the tree rather than named targets then read it as if it were this project: $ git worktree add .claude/worktrees/wip $ poetry run deptry . .claude/worktrees/wip/tests/test_example.py:11:8: DEP004 'pytest' ... Found 4 dependency issues. deptry's default excludes cover a tests directory at the root but not a nested copy of one, so every test import in the second checkout is reported, and task check fails in the parent repository for as long as the worktree exists - while the same checks pass inside the worktree. trivy has the same exposure, and contrary to the report it fails too: check:trivy passes --exit-code 1, and with the lock file committed the scan picks up both copies (num=2), so a worktree on an older branch brings that branch's findings into the parent's check. check:ruff and check:mypy are unaffected: they are given tests and the package as explicit targets. Verified in a rendered plugin case - reproduced both, then confirmed --extend-exclude '\.claude' returns deptry to "Scanning 3 files... no dependency issues" and --skip-dirs .claude returns trivy to one target. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013pwym1cFV5jEhi7LdzKmEY
A task declaring FixedNumberOfInputs([]) never reads the inputs argument of execute(), but WorkflowPlugin decides the signature, so ARG002 cannot be answered by dropping it. The rules listed only PLR0913 and PLR0917 as settled, so every project had to escalate to a human the case the shipped example_workflow.py already resolves with a noqa. The other escape does not hold up. Renaming the argument to _inputs passes both linters - mypy treats an override parameter starting with an underscore as positional-only, and ruff stops reporting it - but the name is part of the API the caller uses: the shipped tests/test_example.py and the plugin-testing skill both call execute(inputs=(), context=...) by keyword, so the rename would raise TypeError against the template's own test, and nothing here can see how DataIntegration invokes it. The example also violated the rule it illustrates: the rules require the reason in a comment above a noqa, and it carried none. It does now. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013pwym1cFV5jEhi7LdzKmEY
The example docstrings said "Remove this and other example files after
bootstrapping your project", which reads as a step of its own. Doing it
before the first real module exists leaves a package with no code, and
task check then fails three times over - reproduced in a rendered plugin
case:
DEP002 'cmem-plugin-base' defined as a dependency but not used
pytest: no tests ran ... exit status 5
genbadge: ValueError: Computed line rate (0) is different from the one
in the file (1.0)
None of the three can be answered without a suppression or a Taskfile
edit, both of which the shipped rules forbid, so the instruction led
somewhere the project is not allowed to leave. All five example files say
the working thing instead: replace them with the first real task or
module, and delete them in that same change.
The report's second suggestion - skipping the coverage badge step on a
package with no statements - is declined and recorded under Deliberate
decisions in CLAUDE.md: pytest exits 5 before genbadge is reached and
deptry is right as well, so silencing the badge alone changes nothing.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013pwym1cFV5jEhi7LdzKmEY
Coverage Report
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Triage of the open
template-feedbackissues — one commit per issue.Accepted
check:deptrygets--extend-exclude '\.claude'andcheck:trivygets--skip-dirs .claude. A git worktree under.claude/worktrees/is a complete second checkout inside the repository, and both checks walk the tree rather than named targets, sotask checkfailed in the parent for as long as a worktree existed. Contrary to the report, trivy fails too:check:trivypasses--exit-code 1, and with the lock committed the scan picks up both copies, so a worktree on an older branch brings that branch's findings into the parent's check.check:ruffandcheck:mypyare unaffected — they are giventestsand the package explicitly.ARG002on an argument whose presence a framework fixes is now named as settled in.claude/rules/copier-template.md, besidePLR0913/PLR0917, with a section in theplugin-implementationskill. The_inputsescape is ruled out on evidence: it passes ruff and mypy (which treats an underscore-prefixed override parameter as positional-only), buttests/test_example.pyand theplugin-testingskill both callexecute(inputs=(), context=…)by keyword, so the rename would raiseTypeErroragainst the template's own test. The example's# noqaalso lacked the reason comment the rules require, and now carries it.task checkthree times over:DEP002on the now unusedcmem-plugin-base,pytestexit 5 on collecting no tests, and genbadge'sComputed line rate (0) is different from the one in the file (1.0).Declined
The second half of #107 — skipping the coverage badge step on a package with no statements — is declined and recorded under Deliberate decisions in
CLAUDE.md.pytestdies before genbadge is reached and deptry is right as well, so silencing the badge alone changes nothing a user notices, and the shell conditional would have to hold on the Windows branch of that task too.Not in this sweep
#99 (a
cliproject type) is left open. It is a newproject_typewith skeleton, skill, dependencies and a test case, it carries its own open design question, and it leans on the intent to movecmemconto the template — a feature decision rather than triage.Verification
task checkgreen across all six cases. Beyond it, because the generated checks and the shipped agent files are its two blind spots:plugincase with a worktree at.claude/worktrees/wip,check:deptryreports success andcheck:trivyscans one lock file with the flag versus two without itclaude -prun inside that case answered the ARG002 question from the shipped rules alone, including why_inputsis wrongNote that #107, #108 and #109 close when a release carries these commits onto
main, not when this merges intodevelop.🤖 Generated with Claude Code
https://claude.ai/code/session_013pwym1cFV5jEhi7LdzKmEY