Skip to content

fix: plugin-definitions QA pass — skill nudge reaches the model, repeated guidance trimmed - #10

Merged
sebastian-iancu merged 6 commits into
mainfrom
fix/plugin-definitions-qa
Oct 6, 2026
Merged

sebastian-iancu merged 6 commits into
mainfrom
fix/plugin-definitions-qa

Conversation

@sebastian-iancu

Copy link
Copy Markdown
Contributor

Summary

A QA pass over the plugin's skills, agent, Cursor rule and hooks, checked against the plugin-dev skill-development, agent-development and hook-development guidance and the current Claude Code hooks and skills docs.

Fixes

  • The skill nudge never reached the model. Under Claude Code, hooks/skill-nudge.sh printed {"systemMessage": …}. The hooks reference defines systemMessage as a "warning message shown to the user"; the model-facing channel is hookSpecificOutput.additionalContext. The hook now uses that, so the nudge can do its job. Cursor still gets a plain line. Tests and the four docs that described the old channel are updated.
  • Unquoted ${CLAUDE_PLUGIN_ROOT} in hooks/hooks.json: claude plugin validate warned that a plugin path containing a space would split the command. It is quoted now and the warnings are gone.
  • go-testing promised a rule it did not have. Its description and the router's Route, then load table send "can-fail control" work to go-testing, but the body never covered it. The rule is added.
  • $CLAUDE_FILE_PATH was described as set by Claude Code; no host sets it. It stays as a test override, and the comments and AGENTS.md now say so.
  • Cursor rule: the layout row now names the same revive rules and gofmt doc-comment layout as the router.

Trims (no rule removed)

Guidance stated two or three times now appears once:

Component Change Size
go-idioms Go 1.27 go fix changes stated once (in Newer in Go 1.27); strings.CutLast/bytes.CutLast get a table row, verified on Go 1.27.1 1,625 → 1,476 words
go-coding gopls advice, a paragraph restating Route, then load, the orchestrator instruction; drops a reference to "the project research", which the consuming model can't see 978 → 914 words
go-lint-setup migrate details and version-pinning advice 944 → 901 words
go-errors, go-testing %v-instead-of-%w; -race; the cryptotest/t.Parallel warning small
go-reviewer description 1,232 → 984 chars (it loads in every session); body 10,682 → 9,994 chars 1,608 → 1,520 words

go-lint-setup now pre-approves Bash(golangci-lint *) instead of all of Bash. The skills docs note that allowed-tools grants are not gated by workspace trust.

Validator

scripts/validate.py now fails when the /go-lint-setup scaffold block and references/golangci.v2.yml enable a different default, linters or formatters. Both copies already said "keep in sync", but nothing enforced it. This extends the existing advice-equals-tooling check, so the documented count of three invariants still holds. A new --selftest case shows the check fires on drift and stays quiet on a clean tree.

For the reviewer

  • The can-fail rule has no style-guide citation; it is the plugin's own practice, as it already was in the router's checklist. Label it as house practice if you prefer.
  • go-reviewer's "Import and literal hygiene" dimension is caught entirely by revive and go vet, which conflicts with the agent's own "don't report what linters catch" rule. It was left in because CHANGELOG 0.6.0 shows it was added on purpose.

Checklist

  • ./scripts/validate.sh passes. The Fixer-column check soft-skipped locally (Go 1.27 on PATH); the Fixer table is unchanged, and CI's 1.26 job runs it.
  • claude plugin validate . passes, with no warnings now.
  • Skill / command / agent triggering tested locally. Not done. Worth one claude --debug session that edits a *.go file, to confirm the nudge arrives as a system reminder.
  • Cursor install tested locally. Not done. The rule and the Claude-side hook output changed; the Cursor hook output did not.
  • Both manifests kept in sync (metadata unchanged)
  • Cursor rule files and the .cursor-plugin/plugin.json path map kept in step (no components added or removed)
  • CHANGELOG.md updated under [Unreleased]; version bump left for the release commit
  • Docs synced: no components added or renamed. AGENTS.md, README.md, docs/install.md and docs/testing.md are updated for the hook change.

Also run: python3 scripts/validate.py --selftest (10/10), ./scripts/hooks-test.sh (28/28), python3 scripts/validate.py --check-links (64/64).

🤖 Generated with Claude Code

@sebastian-iancu
sebastian-iancu merged commit 9a3af4b into main Oct 6, 2026
3 checks passed
sebastian-iancu and others added 6 commits October 6, 2026 14:20
Under Claude Code, skill-nudge.sh printed {"systemMessage": ...}. The hooks
reference defines systemMessage as a warning shown to the user, so the nudge
never reached the model it is meant to steer. It now prints
hookSpecificOutput.additionalContext with hookEventName PostToolUse, which
Claude Code injects as a system reminder next to the tool result. Cursor
still gets a plain line.

hooks.json quotes ${CLAUDE_PLUGIN_ROOT} in each command, clearing the
`claude plugin validate` warning that a path with a space splits the
command.

format-on-save.sh described $CLAUDE_FILE_PATH as set by Claude Code; no host
sets it. It stays as an override for tests and manual runs; the stdin
payload's tool_input.file_path (always absolute) is the real source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both config copies said "keep in sync" and the advice-equals-tooling error
already spoke of "both config copies", but nothing compared them. The
linter-references check now fails when the scaffold block in
skills/go-lint-setup/SKILL.md and references/golangci.v2.yml differ in
linters.default, enabled linters or enabled formatters. A new --selftest
case proves the check fires on drift and stays quiet on a clean tree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
go-testing's description (and the router's Route-then-load table) send
can-fail control work to go-testing, but its body never had the rule. It
now does.

Each of these was stated two or three times and now appears once:
- go-idioms: the Go 1.27 go fix changes (table intro, a loose paragraph,
  and the 1.27 section); strings.CutLast/bytes.CutLast move into the 1.27
  table, and the self-referential-constraints note moves to the no-fixer
  list.
- go-coding: the gopls-lsp advice, a paragraph restating Route-then-load,
  and the orchestrator instruction; drops a reference to "the project
  research" the consuming model cannot see.
- go-errors: the %v-instead-of-%w warning folds into the %w rule.
- go-testing: -race, the cryptotest/t.Parallel warning; the compressed-bytes
  note moves under "Compare stable results".
- go-lint-setup: the migrate details and the version-pinning advice; the
  pointer for what each linter does now names the file that explains it.

go-lint-setup pre-approves Bash(golangci-lint *) rather than all of Bash:
allowed-tools grants are not gated by workspace trust.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tions

The description is loaded into every session; it drops from 1,232 to 984
characters by shortening the dimension list the body already details. The
body drops under 10,000 characters by removing instructions stated two or
three times: the Skill-tool sentence (step 1 says it), the scope rule, the
untrusted-content note, and the paragraph restating steps 1 and 3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Cursor rule named two of the router's five revive rules and omitted
gofmt for doc-comment layout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant