chore(#107): validate-issue-structure.sh PreToolUse hook#122
Merged
Conversation
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.
Summary
Adds a new PreToolUse hook
validate-issue-structure.shthat fires ongh issue createand enforces a body-shape schema per bracketed title prefix. Closes the gap where agents bypass the interactive/feature//task//bugskills and file rawgh issue createwith bespoke body shapes.The rule was already in
.claude/rules/ticket-vocabulary.mdand the individual skill docs, but until now it was self-discipline. This hook is the mechanical backstop: if the body doesn't have the required sections for its prefix, the issue-creation call exits 2 with a message naming the missing sections and pointing at the right skill..claude/hooks/validate-issue-structure.sh(~340 LOC).ticket.required_sections+.ticket.skip_markervia the shared reader from [Chore] Make ticket-prefix whitelist + schema project-configurable (not hardcoded) #109. Extended.claude/project-config.defaults.jsonwith the mapping (Feature → [User Story, Acceptance Criteria]; Chore/Refactor/Testing/CI → [Driver, Scope, Acceptance Criteria]; Docs → [Driver, Acceptance Criteria]; Bug → [Given / When / Then, Repro])..claude/settings.json— PreToolUse matcher onBash(gh issue create *).docs/rule-audit.mdfor the rule; mechanized count bumped.How it works
gh issue createonly. Silent pass on everything else.--titleand--body/--body-file/-F <path>(lifted the arg-extractor style fromblock-private-refs-in-public-repos.sh, with awk-based multi-line body handling so bodies with\nsurvive intact —sedis line-oriented and would have truncated).[Feature],[Chore], etc.), lowercases for the whitelist match, preserves canonical case for the required-sections lookup. Blocks if the prefix isn't whitelisted.## <name>(case-insensitive, with tolerance for## Given/When/Thenvs## Given / When / Thenvs## given/when/then).##(or EOF) and strip whitespace — an empty range fails.<!-- validate-issue-structure: skip -->in the body bypasses with a visible stderr WARN. For epics, meta-threads, parking-lot issues that don't fit the schema.gh issue create), prefix not in the schema, config completely absent.Testing
Rebased cleanly onto the current
devHEAD after #111 landed — auto-merge of.claude/project-config.defaults.json(nestedticketsubtree gainedrequired_sections+skip_marker) anddocs/rule-audit.md(new row at section 11). Both resolved without conflict.Scope — what this does NOT do
/feature//task//bugskill files — they already reference config in their Rules sections (landed in [Chore] Make ticket-prefix whitelist + schema project-configurable (not hardcoded) #109).validate-pr-create.sh— that's separate ([Chore] Require Testing section in PR body (extend validate-pr-create.sh) #113 / [Chore] Enforce single Closes-keyword per PR body (one ticket per PR) #114).--body-file -(stdin) shape is a known gap — the hook silently skips rather than trying to read stdin, same pattern as sibling hooks. Low frequency, noted in the header comment.Follow-ups
[Infra],[Scaffold],[Design],[Security]) — teams extend by adding to.ticket.prefix_whitelist+.ticket.required_sectionsin their per-forkproject-config.json. No framework edits required per apexyard#109's config-driven design.Glossary
## Name) that must appear in the body with non-empty content..ticket.prefix_whitelist.##— if there's no non-whitespace content, the section is flagged as empty.<!-- validate-issue-structure: skip -->— bypasses validation for one invocation with a visible WARN.Closes #107