Driver
Agents routinely bypass the /feature, /bug, and /task skills when filing tickets in bulk. The skills are interactive (one-question-at-a-time, per their own rule), which makes them impractical for "file 10 tickets right now" intents — the agent silently falls back to raw gh issue create with bespoke body shapes. Result: tickets that are information-rich but don't match the team standard.
The failure happened before any tool call — self-discipline prose ("BLOCKING REQUIREMENT: invoke the relevant Skill tool") did not prevent it. Precedent for mechanical enforcement of this class of rule: validate-commit-format.sh, validate-pr-create.sh.
Scope
Add .claude/hooks/validate-issue-structure.sh, wired to PreToolUse on Bash matching gh issue create …. The hook:
- Parses command args to extract
--title and --body (or --body-file).
- Extracts the title prefix (
[Foo] style) and looks up the expected body schema from project config (see below) — never hardcoded.
- Enforces the schema: required sections must be present; checkbox counts must be > 0 where configured.
- On fail: exits 2 with a message that names the missing section and suggests the matching skill.
- Skip condition: body contains
<!-- validate-issue-structure: skip --> — escape hatch for legitimate off-template tickets (epics, meta-threads).
Config-driven — not hardcoded
A separate .claude/project-config.json (or an extension to onboarding.yaml) carries the team's ticket schema. Default ships with the current skill templates; teams override without touching framework code.
ticket:
prefix_whitelist: [Feature, Bug, Chore, Refactor, Testing, CI, Docs]
required_sections:
Feature: ["User Story", "Acceptance Criteria"]
Chore: ["Driver", "Scope", "Acceptance Criteria"]
Bug: ["Given / When / Then", "Repro"]
Docs: ["Driver", "Acceptance Criteria"]
label_priority_scheme: "P0,P1,P2,P3" # some teams use priority-p0 etc
The hook, /feature, /task, /bug, and the batch skill (companion ticket) all read from the same config. One source of truth per project; zero coupling in framework code to any specific team's conventions.
Acceptance Criteria
Risks / Dependencies
- Blocked by the config format landing — the hook enforces against something, and that something is the config schema. The companion config-and-whitelist ticket lands first.
- Edge case: legitimate off-template tickets (epics, meta-threads). The skip marker handles this; document it in the rule file so contributors don't guess.
- Over-strict parsing would false-positive. Mitigation: grep for headers, don't parse markdown trees. Start permissive, tighten after logs.
Glossary
| Term |
Definition |
| PreToolUse hook |
Shell script invoked by Claude Code before a tool call. Exit 0 allows; exit 2 blocks with a message shown to the user and agent. |
| Skip marker |
HTML comment in the body telling the hook to let this invocation through. Keeps the escape hatch explicit and grep-able. |
Driver
Agents routinely bypass the
/feature,/bug, and/taskskills when filing tickets in bulk. The skills are interactive (one-question-at-a-time, per their own rule), which makes them impractical for "file 10 tickets right now" intents — the agent silently falls back to rawgh issue createwith bespoke body shapes. Result: tickets that are information-rich but don't match the team standard.The failure happened before any tool call — self-discipline prose ("BLOCKING REQUIREMENT: invoke the relevant Skill tool") did not prevent it. Precedent for mechanical enforcement of this class of rule:
validate-commit-format.sh,validate-pr-create.sh.Scope
Add
.claude/hooks/validate-issue-structure.sh, wired toPreToolUseonBashmatchinggh issue create …. The hook:--titleand--body(or--body-file).[Foo]style) and looks up the expected body schema from project config (see below) — never hardcoded.<!-- validate-issue-structure: skip -->— escape hatch for legitimate off-template tickets (epics, meta-threads).Config-driven — not hardcoded
A separate
.claude/project-config.json(or an extension toonboarding.yaml) carries the team's ticket schema. Default ships with the current skill templates; teams override without touching framework code.The hook,
/feature,/task,/bug, and the batch skill (companion ticket) all read from the same config. One source of truth per project; zero coupling in framework code to any specific team's conventions.Acceptance Criteria
validate-issue-structure.shexists and is executable..claude/project-config.json(or the chosen config location) with a baked-in default that ships with the framework..claude/hooks/tests/cover pass and fail paths per prefix..claude/settings.jsonwired with the matcher.docs/rule-audit.mdlists the hook.Risks / Dependencies
Glossary