Skip to content

(feat): Add issue field validation workflow and structured issue templates#237

Closed
JustAGhosT wants to merge 6 commits intodevfrom
claude/improve-issue-template-Ci6Wc
Closed

(feat): Add issue field validation workflow and structured issue templates#237
JustAGhosT wants to merge 6 commits intodevfrom
claude/improve-issue-template-Ci6Wc

Conversation

@JustAGhosT
Copy link
Collaborator

Summary

Implements automated issue field validation and converts issue templates from Markdown to structured YAML forms with dropdown fields. This enables consistent issue intake, automatic label assignment, and team routing based on issue metadata (area, priority, severity, impact).

Closes #

Changes

  • Add GitHub Actions workflow (issue-label-validation.yml) to validate issue fields on creation/edit
  • Convert bug report and feature request templates to YAML form format with dropdown fields
  • Add issue template configuration (config.yml) to disable blank issues
  • Extend task-protocol with P4 priority level and area/severity fields
  • Add resolveTeamByArea() and computeEscalation() functions to orchestrator for issue routing
  • Extend spec-validator with canonical issue field enums (area, priority, severity, impact)
  • Add issue template field validation to validate.mjs
  • Add normalizeSeverity() helper to review-runner for severity normalization
  • Update teams.yaml with CLI and sync-engine area routing
  • Update documentation (sync-backlog.prompt.md, backlog template) with area labels and escalation rules
  • Remove old Markdown issue templates

Test Plan

The validation workflow is automatically triggered on issue open/edit events. Manual testing:

  1. Create a new issue using the bug report template
  2. Verify dropdown fields are present for: Area, Priority, Severity, Phase, Impact Scope
  3. Submit with valid values → should auto-apply labels (e.g., area:backend, priority:p0)
  4. Edit issue with invalid field value → should post validation error comment and apply invalid-fields label
  5. Verify resolveTeamByArea() correctly maps areas to teams per teams.yaml routing
  6. Verify computeEscalation() applies escalation rules (critical security bugs, P0 all-users impact, etc.)

Validation logic is covered by:

  • Issue template field validation in validate.mjs (runs during agentkit:sync)
  • GitHub Actions workflow validation (runs on issue events)
  • Enum definitions in spec-validator.mjs kept in sync with templates

Checklist

  • Tests pass locally (validation logic tested via validate.mjs)
  • Linter passes with no new warnings
  • Build succeeds
  • Documentation updated (sync-backlog.prompt.md, backlog template)
  • No secrets, tokens, or credentials in the diff
  • Reviewed own diff before requesting review

Documentation

Change Impact

  • High — New issue intake system, structured templates, automated routing and escalation

Documentation Checklist

  • History document created (if applicable)
  • sync-backlog.prompt.md updated with area routing table and escalation rules
  • Backlog template updated with area labels and severity field
  • Issue template comments include generation source and regeneration instructions

https://claude.ai/code/session_01Ue9aaiqqt1iHDx8KNwQ92m

claude added 2 commits March 4, 2026 20:19
…y, phase, and impact fields

Convert issue templates from Markdown to GitHub YAML issue forms with
validated dropdown fields. Add feature request template alongside the
existing bug report. New fields (area, priority, severity, phase, impact)
use preset values derived from teams.yaml and project.yaml enums.

Changes:
- Replace .github/ISSUE_TEMPLATE/bug_report.md with bug_report.yml (YAML form)
- Add .github/ISSUE_TEMPLATE/feature_request.yml with matching fields
- Add .github/ISSUE_TEMPLATE/config.yml (disable blank issues, link security advisories)
- Add .github/workflows/issue-label-validation.yml (validates fields on issue open/edit,
  auto-applies area:/priority:/severity: labels)
- Update .agentkit/templates/github/ISSUE_TEMPLATE/ source templates
- Add issueArea, issuePriority, issueSeverity, issueImpact enums to spec-validator
- Add Phase 9 to validate.mjs: validates issue template dropdown values against enums

https://claude.ai/code/session_01Ue9aaiqqt1iHDx8KNwQ92m
… and task protocol

Wire the new issue area/priority/severity/impact fields into the agent
teams orchestration pipeline so issues flow through to the right teams
automatically.

Changes:
- task-protocol: add area, severity fields to task schema with validation,
  filtering, and display; extend TASK_PRIORITIES to include P4
- orchestrator: add resolveTeamByArea() for area→team routing using
  teams.yaml intake.routing; add computeEscalation() for dynamic
  escalation based on severity + impact + area
- review-runner: normalize severity values to canonical lowercase
  (critical/high/medium/low) matching issue templates; export
  normalizeSeverity() helper
- sync-backlog template: add area labels table, severity levels,
  escalation rules, source tracking, and P4 priority level
- sync-backlog prompt: add issue field routing table and escalation rules
  for Copilot prompt
- teams.yaml: add cli→backend and sync-engine→devops intake routing

https://claude.ai/code/session_01Ue9aaiqqt1iHDx8KNwQ92m
@github-actions
Copy link

github-actions bot commented Mar 4, 2026

AgentKit Forge Source Change Detected

This PR modifies files in the AgentKit Forge source directories:

  • .agentkit/templates/ — output templates
  • .agentkit/spec/ — YAML specifications
  • .agentkit/engines/ — sync engine code
  • .agentkit/overlays/ — per-repo customizations
  • .agentkit/bin/ — CLI scripts

These are the upstream source-of-truth for all generated AI tool configs.

Review checklist

  • Changes are intentional and not accidental AI agent modifications
  • Spec schema validation passes (pnpm -C .agentkit agentkit:spec-validate)
  • Sync produces expected output (pnpm -C .agentkit agentkit:sync)
  • No secrets or credentials in template variables
  • Breaking changes documented in an ADR

AI agents: Do not modify these files directly. Propose changes in a dedicated PR.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 4, 2026

Warning

Rate limit exceeded

@JustAGhosT has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 24 minutes and 53 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1c518730-0bea-4c78-ad13-149db5ab7250

📥 Commits

Reviewing files that changed from the base of the PR and between 25578cb and 31592d2.

📒 Files selected for processing (27)
  • .agentkit/engines/node/src/__tests__/orchestrator.test.mjs
  • .agentkit/engines/node/src/__tests__/review-runner.test.mjs
  • .agentkit/engines/node/src/__tests__/validate.test.mjs
  • .agentkit/engines/node/src/orchestrator.mjs
  • .agentkit/engines/node/src/review-runner.mjs
  • .agentkit/engines/node/src/spec-validator.mjs
  • .agentkit/engines/node/src/synchronize.mjs
  • .agentkit/engines/node/src/task-protocol.mjs
  • .agentkit/engines/node/src/validate.mjs
  • .agentkit/spec/teams.yaml
  • .agentkit/templates/claude/commands/project-review.md
  • .agentkit/templates/claude/commands/review.md
  • .agentkit/templates/claude/commands/sync-backlog.md
  • .agentkit/templates/codex/skills/TEMPLATE/SKILL.md
  • .agentkit/templates/copilot/prompts/TEMPLATE.prompt.md
  • .agentkit/templates/cursor/commands/TEMPLATE.md
  • .agentkit/templates/github/ISSUE_TEMPLATE/bug_report.md
  • .agentkit/templates/github/ISSUE_TEMPLATE/bug_report.yml
  • .agentkit/templates/github/ISSUE_TEMPLATE/config.yml
  • .agentkit/templates/github/ISSUE_TEMPLATE/feature_request.yml
  • .agentkit/templates/windsurf/templates/command.md
  • .github/ISSUE_TEMPLATE/bug_report.md
  • .github/ISSUE_TEMPLATE/bug_report.yml
  • .github/ISSUE_TEMPLATE/config.yml
  • .github/ISSUE_TEMPLATE/feature_request.yml
  • .github/prompts/sync-backlog.prompt.md
  • .github/workflows/issue-label-validation.yml
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/improve-issue-template-Ci6Wc

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

claude added 2 commits March 4, 2026 20:51
…s and flows

Ensure consistent area/priority/severity values in GitHub issue filing,
Linear issue filing, and all platform command templates (Copilot, Cursor,
Windsurf, Codex).

Changes:
- review.md: normalize severity from CRITICAL/HIGH/MEDIUM/LOW to canonical
  lowercase (critical/high/medium/low); add area field to issue filing with
  file-path→area mapping; use structured labels (severity:X, area:X, priority:X)
  for both GitHub and Linear
- project-review.md: same severity normalization and structured label format;
  add area field to Phase 1c findings; add canonical field reference section
- Copilot TEMPLATE.prompt.md: add issue field routing section with area→team
  mapping, priority/severity enums, and escalation rules
- Cursor TEMPLATE.md: same routing section added
- Windsurf command.md: same routing section added
- Codex SKILL.md: same routing section added

All platforms now reference identical:
  - Area values (12 canonical values from teams.yaml)
  - Priority levels (P0–P4)
  - Severity levels (critical/high/medium/low)
  - Escalation rules (severity+area→security teams, impact+P0→product)

https://claude.ai/code/session_01Ue9aaiqqt1iHDx8KNwQ92m
…robustness

Required fixes:
- review.md: fix uppercase "CRITICAL→P0, HIGH→P1" to lowercase "critical→P0, high→P1"
- validate.mjs Phase 9: make area parsing consistent with severity — extract
  bare value before " — " separator so "backend — Server-side" validates correctly
- (PROJECT_ENUMS export verified as already present on line 1086)

Tests:
- orchestrator.test.mjs: add tests for resolveTeamByArea() (default routing,
  unknown areas, config overrides, team- prefix handling) and computeEscalation()
  (security escalation, blocked cross-team, operations team from config, edge cases)
- review-runner.test.mjs: add tests for normalizeSeverity() (uppercase, lowercase,
  mixed case, unknown values)
- validate.test.mjs: add Phase 9 tests (valid dropdowns, invalid area, invalid
  severity, malformed template, area options with description separators)

DRY improvements:
- synchronize.mjs: add buildAreaRoutingTable() to generate routing from teams.yaml
  and expose as {{intakeAreaRoutingTable}} template variable
- All 4 platform templates (Copilot, Cursor, Windsurf, Codex) now use
  {{intakeAreaRoutingTable}} instead of hardcoded routing strings

Performance:
- orchestrator.mjs: add loadTeamsSpec() cache (Map keyed by agentkitRoot) so
  resolveTeamByArea() and computeEscalation() read teams.yaml at most once per
  process. Export clearTeamsSpecCache() for test isolation.

Robustness:
- computeEscalation(): read operationsTeam from teams.yaml config instead of
  hardcoding 'team-quality'
- issue-label-validation.yml: add workflow_dispatch trigger with optional
  issue_number input for manual dry-run testing

All 597 tests pass.

https://claude.ai/code/session_01Ue9aaiqqt1iHDx8KNwQ92m
Copilot AI review requested due to automatic review settings March 4, 2026 23:28
The Copilot prompt template now uses {{intakeAreaRoutingTable}} which
renders the area→team routing as a compact inline string instead of a
full markdown table.

https://claude.ai/code/session_01Ue9aaiqqt1iHDx8KNwQ92m
@JustAGhosT JustAGhosT changed the title Add issue field validation workflow and structured issue templates (feat): Add issue field validation workflow and structured issue templates Mar 4, 2026
@JustAGhosT JustAGhosT marked this pull request as ready for review March 4, 2026 23:36
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements structured GitHub Issue Forms and adds automated validation/routing primitives so issue intake can be normalized (area/priority/severity/impact), consistently labeled, and used for team routing + escalation across AgentKit templates and engines.

Changes:

  • Added a GitHub Actions workflow to validate issue form fields and apply labels on issue open/edit.
  • Converted bug/feature issue templates to YAML issue forms and disabled blank issues.
  • Extended AgentKit engine/spec to include canonical enums + routing/escalation helpers and updated prompts/templates accordingly.

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
.github/workflows/issue-label-validation.yml Adds issue field validation + auto-labeling on issue events.
.github/prompts/sync-backlog.prompt.md Documents area routing + escalation rules for backlog sync.
.github/ISSUE_TEMPLATE/feature_request.yml New structured Issue Form for feature requests (dropdown metadata).
.github/ISSUE_TEMPLATE/config.yml Disables blank issues; adds security advisory contact link.
.github/ISSUE_TEMPLATE/bug_report.yml New structured Issue Form for bug reports (adds severity, etc.).
.github/ISSUE_TEMPLATE/bug_report.md Removes legacy Markdown bug template.
.agentkit/templates/windsurf/templates/command.md Injects area routing + severity/priority guidance into generated commands.
.agentkit/templates/github/ISSUE_TEMPLATE/feature_request.yml Adds template source for generating feature request issue form.
.agentkit/templates/github/ISSUE_TEMPLATE/config.yml Adds template source for generating issue template config (blank issues disabled + contact link).
.agentkit/templates/github/ISSUE_TEMPLATE/bug_report.yml Adds template source for generating bug report issue form.
.agentkit/templates/github/ISSUE_TEMPLATE/bug_report.md Removes legacy Markdown bug template from template source.
.agentkit/templates/cursor/commands/TEMPLATE.md Adds issue routing/escalation guidance to Cursor command template.
.agentkit/templates/copilot/prompts/TEMPLATE.prompt.md Adds issue routing/escalation guidance to Copilot prompt template.
.agentkit/templates/codex/skills/TEMPLATE/SKILL.md Adds issue routing/escalation guidance to Codex skill template.
.agentkit/templates/claude/commands/sync-backlog.md Updates backlog item format (adds severity/source) + routing/escalation rules.
.agentkit/templates/claude/commands/review.md Normalizes severity taxonomy to lowercase canonical values; updates issue-filing labels/fields.
.agentkit/templates/claude/commands/project-review.md Aligns project-review output + issue filing to canonical area/priority/severity fields.
.agentkit/spec/teams.yaml Extends intake routing to include cli and sync-engine areas.
.agentkit/engines/node/src/validate.mjs Adds “Phase 9” validation to ensure issue template dropdown options match canonical enums.
.agentkit/engines/node/src/task-protocol.mjs Extends task protocol with P4 + optional area/severity fields and filtering/formatting.
.agentkit/engines/node/src/synchronize.mjs Adds generation of intakeAreaRoutingTable template var from teams intake routing.
.agentkit/engines/node/src/spec-validator.mjs Introduces canonical enums for issue fields (area/priority/severity/impact).
.agentkit/engines/node/src/review-runner.mjs Adds normalizeSeverity() helper; normalizes automated scan severities to lowercase.
.agentkit/engines/node/src/orchestrator.mjs Adds resolveTeamByArea() and computeEscalation() with teams.yaml-backed behavior + caching.
.agentkit/engines/node/src/__tests__/validate.test.mjs Adds tests covering the new issue template validation phase.
.agentkit/engines/node/src/__tests__/review-runner.test.mjs Adds tests for normalizeSeverity().
.agentkit/engines/node/src/__tests__/orchestrator.test.mjs Adds tests for routing + escalation helpers (incl config overrides).

uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

workflow_dispatch runs will fail because context.payload.issue is undefined for that event type. Either remove workflow_dispatch, or implement the issue_number input by fetching the issue via the REST API before accessing issue.body/issue.number (and skip label/comment writes when running in dry-run mode).

Suggested change
const issue = context.payload.issue;
// Support both `issues` and `workflow_dispatch` events.
// For `issues`, `context.payload.issue` is populated.
// For `workflow_dispatch`, we expect an `issue_number` input and fetch the issue via REST.
const eventName = context.eventName;
const inputs = (context.payload && context.payload.inputs) || {};
const issueNumberInput = inputs.issue_number;
let issue = context.payload.issue;
if (!issue) {
if (!issueNumberInput) {
core.setFailed('No issue context available. For workflow_dispatch, provide the "issue_number" input.');
return;
}
const { data } = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: Number(issueNumberInput),
});
issue = data;
}
const DRY_RUN = eventName === 'workflow_dispatch';

Copilot uses AI. Check for mistakes.
Comment on lines +76 to +82
errors.push(`**Area** "${area}" is not a valid option. Allowed: ${ALLOWED_AREAS.join(', ')}`);
}

// Validate priority (required)
const priority = extractField(body, 'Priority');
if (priority && !ALLOWED_PRIORITIES.includes(priority)) {
errors.push(`**Priority** "${priority}" is not a valid option. Must be P0–P4.`);
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script comments indicate Area/Priority are required, but missing values currently pass validation (no error, no invalid-fields label). To enforce consistent intake/routing (and to handle legacy/non-template issues), add explicit errors when required fields are absent (including when rendered as _No response_).

Suggested change
errors.push(`**Area** "${area}" is not a valid option. Allowed: ${ALLOWED_AREAS.join(', ')}`);
}
// Validate priority (required)
const priority = extractField(body, 'Priority');
if (priority && !ALLOWED_PRIORITIES.includes(priority)) {
errors.push(`**Priority** "${priority}" is not a valid option. Must be P0–P4.`);
errors.push(`**Area** "${area}" is not a valid option. Allowed: ${ALLOWED_AREAS.join(', ')}`);
} else if (!area) {
errors.push('**Area** is required and must be set to a valid option.');
}
// Validate priority (required)
const priority = extractField(body, 'Priority');
if (priority && !ALLOWED_PRIORITIES.includes(priority)) {
errors.push(`**Priority** "${priority}" is not a valid option. Must be P0–P4.`);
} else if (!priority) {
errors.push('**Priority** is required and must be set to a valid option.');

Copilot uses AI. Check for mistakes.
Comment on lines +103 to +178
// Apply area label
if (area && ALLOWED_AREAS.includes(area)) {
try {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
labels: [`area:${area}`]
});
} catch (e) {
core.warning(`Could not add label area:${area} — ${e.message}`);
}
}

// Apply priority label
if (priority) {
const prioMatch = priority.match(/^(P\d)/);
if (prioMatch) {
try {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
labels: [`priority:${prioMatch[1].toLowerCase()}`]
});
} catch (e) {
core.warning(`Could not add priority label — ${e.message}`);
}
}
}

// Apply severity label (bug reports)
if (severity) {
const sevLevel = severity.split(' — ')[0];
if (sevLevel) {
try {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
labels: [`severity:${sevLevel}`]
});
} catch (e) {
core.warning(`Could not add severity label — ${e.message}`);
}
}
}

// Post validation comment if errors found
if (errors.length > 0) {
const comment = [
'## Issue Field Validation Failed',
'',
'The following fields have invalid values:',
'',
...errors.map(e => `- ${e}`),
'',
'Please edit this issue and select valid options from the dropdowns.',
'',
'---',
'*This check is automated by AgentKit Forge issue field validation.*'
].join('\n');

await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: comment
});

await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
labels: ['invalid-fields']
});
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On issue edits, this only ever adds labels; it never removes stale area:*, priority:*, severity:*, or invalid-fields labels when a user changes/fixes the fields. This can leave issues with conflicting labels and permanently-marked invalid state; consider reconciling current labels to the latest field values (remove old labels, and remove invalid-fields when errors.length === 0).

Copilot uses AI. Check for mistakes.
Comment on lines +151 to +171
// Post validation comment if errors found
if (errors.length > 0) {
const comment = [
'## Issue Field Validation Failed',
'',
'The following fields have invalid values:',
'',
...errors.map(e => `- ${e}`),
'',
'Please edit this issue and select valid options from the dropdowns.',
'',
'---',
'*This check is automated by AgentKit Forge issue field validation.*'
].join('\n');

await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: comment
});
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validation comments and error bullets embed user-controlled field values (e.g. area, priority) directly into Markdown. A malicious edit could inject @mentions/links and cause notification spam; consider escaping/formatting values safely (e.g. wrap in code spans and neutralize @), and avoid repeatedly posting new comments on every edit when the same validation failure persists.

Copilot uses AI. Check for mistakes.
blank_issues_enabled: false
contact_links:
- name: Security Vulnerability
url: https://github.com/{{repoName}}/security/advisories/new
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{repoName}} is configured in overlays as a bare repo name (e.g. pvc-costops-analytics), not an owner/repo slug, so this URL will be invalid for most generated repos. Prefer generating a dedicated githubRepository/repoFullName template var (from git remote or explicit spec), or change the template to avoid requiring the owner (e.g. instruct users to fill it in during init).

Suggested change
url: https://github.com/{{repoName}}/security/advisories/new
url: https://github.com/OWNER/REPO/security/advisories/new

Copilot uses AI. Check for mistakes.
JustAGhosT added a commit that referenced this pull request Mar 5, 2026
Merge PR #237 changes into fresh branch from dev.
Resolve merge conflict in synchronize.mjs by keeping both
buildTeamVars and buildAreaRoutingTable functions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@JustAGhosT
Copy link
Collaborator Author

Superseded by #284 — all changes consolidated, review comments addressed, and tests passing.

@JustAGhosT JustAGhosT closed this Mar 5, 2026
@JustAGhosT JustAGhosT deleted the claude/improve-issue-template-Ci6Wc branch March 5, 2026 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants