Skip to content

feat(jira): add agent-eval-harness eval for jira:create skill - #615

Draft
cblecker wants to merge 1 commit into
openshift-eng:mainfrom
cblecker:feat/jira-create-eval
Draft

feat(jira): add agent-eval-harness eval for jira:create skill#615
cblecker wants to merge 1 commit into
openshift-eng:mainfrom
cblecker:feat/jira-create-eval

Conversation

@cblecker

@cblecker cblecker commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds first agent-eval-harness eval for the jira plugin, targeting the jira:create skill (which implicitly tests jira:jira-conventions)
  • 14 test cases covering all 6 issue types, all active convention files (CNTRLPLANE, OCPBUGS, GCP-HCP, HyperShift), plus validation edge cases
  • Uses dry-run approach: system prompt instructs skill to write planned-call.json instead of calling createJiraIssue MCP, with all MCP tools denied — no Jira auth needed, no garbage issues created
  • 8 judges: 6 programmatic Python checks + 2 LLM judges (Opus)

Test case coverage

Case Type Project Convention Tests
001 story CNTRLPLANE cntrlplane Version normalization, user story format
002 bug OCPBUGS ocpbugs Dual version fields (versions vs customfield_10855)
003 epic CNTRLPLANE cntrlplane Epic Name custom field, parent linking
004 story CNTRLPLANE hypershift ARO component auto-detection, aro-hcp label
005 bug OCPBUGS ocpbugs+hypershift Layered conventions, ROSA component
006 task CNTRLPLANE cntrlplane Plain task, no team conventions
007 feature CNTRLPLANE cntrlplane Feature template, strategic value
008 feature-request RFE none RFE project default, 4-question workflow
009 story GCP gcp-hcp GCP templates, story points auto-estimation
010 bug OCPBUGS ocpbugs --version flag, version format
011 story CNTRLPLANE hypershift ROSA HCP keywords, rosa-hcp label
012 epic GCP gcp-hcp GCP epic conventions, Epic Name field
013 story CNTRLPLANE cntrlplane Summary anti-pattern validation ("As a...")
014 bug OCPBUGS ocpbugs Security scan blocks credentials in content

Test plan

  • Run make lint — passes with A+ grade (verified locally)
  • Run single case locally: claude --plugin-dir /tmp/agent-eval-harness --plugin-dir plugins/jira -p "/eval-run --config plugins/jira/evals/eval-create.yaml --model claude-sonnet-4-20250514 --cases case-001-story-cntrlplane-basic"
  • Verify dry-run system prompt override works (skill writes planned-call.json instead of calling MCP)
  • Run full eval suite and tune thresholds based on results
  • Add ci-operator test entry in openshift/release (follow-up PR)

Summary by CodeRabbit

  • New Features
    • Added 14 Jira issue-creation evaluation scenarios covering stories, bugs, epics, tasks, features, and feature requests.
    • Added coverage for project conventions, version handling, components, custom fields, descriptions, labels, and parent linking.
    • Added security validation coverage to detect credentials and block unsafe issue creation.
    • Added automated evaluation configuration for validating generated Jira issue payloads and descriptions.

Add eval definition and 14 test cases covering all 6 issue types
(story, bug, epic, feature, task, feature-request), all active
convention files (CNTRLPLANE, OCPBUGS, GCP-HCP, HyperShift), and
validation edge cases (bad summary anti-pattern, credential detection).

Uses dry-run approach: system prompt instructs the skill to write
planned-call.json instead of calling createJiraIssue MCP, with all
MCP tools denied in permissions. This tests type routing, convention
loading, smart defaults, field formatting, and validation without
creating real Jira issues.

8 judges: 6 programmatic (output exists, valid JSON, universal
defaults, correct issue type, correct project key, convention fields)
and 2 LLM (description quality, convention compliance).

Assisted-by: Claude:claude-opus-4-6
@openshift-ci

openshift-ci Bot commented Jul 10, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 10, 2026
@openshift-ci

openshift-ci Bot commented Jul 10, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cblecker

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 10, 2026
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds fourteen Jira create evaluation cases covering issue types, projects, conventions, versions, custom fields, validation warnings, and credential blocking. Adds eval-create.yaml with DRY RUN execution, output contracts, structural judges, convention checks, and LLM rubric judges.

Changes

Jira create evaluation coverage

Layer / File(s) Summary
Evaluation execution and output contract
plugins/jira/evals/eval-create.yaml
Configures case-driven DRY RUN execution, dataset schemas, required JSON outputs, tracing, and evaluation metadata.
Issue-type and convention fixture matrix
plugins/jira/evals/cases/create/case-00[1-4]-*/*, plugins/jira/evals/cases/create/case-006-*/*, plugins/jira/evals/cases/create/case-007-*/*, plugins/jira/evals/cases/create/case-008-*/*, plugins/jira/evals/cases/create/case-009-*/*
Adds baseline story, bug, epic, task, feature, feature-request, and GCP-HCP cases with expected metadata and descriptions.
Specialized version and team fixtures
plugins/jira/evals/cases/create/case-005-*/*, plugins/jira/evals/cases/create/case-011-*/*, plugins/jira/evals/cases/create/case-012-*/*, plugins/jira/evals/cases/create/case-010-*/*
Adds HyperShift, ROSA, OCPBUGS version, and GCP Epic cases covering components, labels, version formats, and custom fields.
Structural, convention, and security judging
plugins/jira/evals/cases/create/case-013-*/*, plugins/jira/evals/cases/create/case-014-*/*, plugins/jira/evals/eval-create.yaml
Adds summary-warning and credential-blocking fixtures plus judges for JSON structure, defaults, identity fields, conventions, descriptions, compliance, and blocked creation.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant EvaluationModel
  participant JiraCreateSkill
  participant Workspace
  participant EvalJudges
  EvaluationModel->>JiraCreateSkill: generate createJiraIssue arguments in DRY RUN
  JiraCreateSkill->>Workspace: write planned-call.json and validation-results.json
  Workspace->>EvalJudges: provide evaluation outputs
  EvalJudges->>EvalJudges: validate structure, defaults, conventions, descriptions, and blocking
Loading

Possibly related PRs

Suggested labels: ok-to-test, jira/valid-reference

Suggested reviewers: jogeo, Prashanth684, enxebre

🚥 Pre-merge checks | ✅ 10
✅ Passed checks (10 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding an agent-eval-harness evaluation for the Jira create skill.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No Real People Names In Style References ✅ Passed No real-person names appear as style references or examples in the added Jira eval prompts/docs; only model, product, and metadata terms are used.
No Assumed Git Remote Names ✅ Passed Changed files contain no hardcoded git remote names or remote-command assumptions.
Git Push Safety Rules ✅ Passed PR only adds Jira eval YAMLs; no git push, force-push, or main/master push commands appear in the changed files or eval config.
No Untrusted Mcp Servers ✅ Passed PR only adds eval YAML; no npm/npx/GitHub MCP server installs or new server deps. It explicitly denies mcp__* tools instead of adding them.
Ai-Helpers Overlap Detection ✅ Passed PR only changes plugins/jira/evals YAMLs; no files under plugins//commands/.md, plugins//skills//SKILL.md, or agents/*.md are modified.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/jira/evals/cases/create/case-003-epic-cntrlplane/annotations.yaml`:
- Around line 17-19: Update the create-case assertions for the CNTRLPLANE epic
to explicitly validate that additional_fields.parent.key equals
"CNTRLPLANE-500", either by adding a parent assertion or a dedicated judge
alongside the existing Epic Name check.

In
`@plugins/jira/evals/cases/create/case-004-story-hypershift-aro/annotations.yaml`:
- Around line 8-9: The annotation only validates that customfield_10855 is an
array and does not verify the requested version. Add a normalized openshift-4.22
expectation to this case’s annotations, or update the relevant judge logic to
resolve and compare the version value while preserving the existing array-shape
check.

In
`@plugins/jira/evals/cases/create/case-005-bug-ocpbugs-hypershift-rosa/annotations.yaml`:
- Around line 8-10: The annotations for this fixture only validate types and
presence, not the expected values. Update the executable assertions using
expected_version_field and expected_affects_version to require customfield_10855
to equal openshift-4.22 and the affects-version entry to exactly equal 4.21,
adding a machine-readable expected target-version value as needed.

In `@plugins/jira/evals/cases/create/case-009-story-gcp-hcp/annotations.yaml`:
- Around line 11-12: The convention_fields_applied judge must validate the value
of customfield_10028, not merely its presence. Update the relevant comparison
logic to read the expected value from expected_custom_fields and compare it with
the generated field using numeric normalization so equivalent numeric
representations pass while incorrect estimates fail.

In `@plugins/jira/evals/cases/create/case-012-epic-gcp-hcp/annotations.yaml`:
- Around line 17-20: Make the no-story-points requirement machine-checkable in
the epic evaluation annotations: add an explicit assertion or forbidden-field
check alongside the existing template and custom-field checks, targeting the
story-points field so the case fails whenever an epic contains story points.

In `@plugins/jira/evals/eval-create.yaml`:
- Around line 340-385: The blocked-case evaluation prompt lacks the validation
evidence needed to assess detection and guidance. Update the prompt’s
planned-call section to also load and display validation-results.json from the
outputs, so the judge can verify the warning and guidance; retain the existing
annotations and rubric.
- Around line 41-49: The eval assertions must enforce the complete validation
output contract. Update the relevant judge logic to require both
validation-results.json and planned-call.json, validate validation-results.json
fields and types, compare summary_warnings and security_warnings against
expected_validation_warnings, and require creation_blocked to be true for
credential-detected cases while planned-call.json is exactly {}.
- Around line 160-164: The validation logic for the createJiraIssue judge must
enforce every field in the prompt contract. Update the required fields list in
the validation block to include cloudId, projectKey, issueTypeName, summary,
description, contentFormat, and additional_fields, so malformed calls cannot
pass the structural gate.
- Around line 294-321: The validation logic in the eval’s version,
affects-version, and custom-field checks only verifies presence or broad type,
not expected values. Update the relevant checks to honor
expected_affects_version, compare each expected_custom_fields entry against its
expected_val, validate version item shape and normalized values, and use
expected_version_field when selecting the version field; preserve clear errors
and details for mismatches.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 2e1539f7-8846-45bd-9ab0-d7db415158d6

📥 Commits

Reviewing files that changed from the base of the PR and between 2a83f75 and 4576259.

📒 Files selected for processing (29)
  • plugins/jira/evals/cases/create/case-001-story-cntrlplane-basic/annotations.yaml
  • plugins/jira/evals/cases/create/case-001-story-cntrlplane-basic/input.yaml
  • plugins/jira/evals/cases/create/case-002-bug-ocpbugs-basic/annotations.yaml
  • plugins/jira/evals/cases/create/case-002-bug-ocpbugs-basic/input.yaml
  • plugins/jira/evals/cases/create/case-003-epic-cntrlplane/annotations.yaml
  • plugins/jira/evals/cases/create/case-003-epic-cntrlplane/input.yaml
  • plugins/jira/evals/cases/create/case-004-story-hypershift-aro/annotations.yaml
  • plugins/jira/evals/cases/create/case-004-story-hypershift-aro/input.yaml
  • plugins/jira/evals/cases/create/case-005-bug-ocpbugs-hypershift-rosa/annotations.yaml
  • plugins/jira/evals/cases/create/case-005-bug-ocpbugs-hypershift-rosa/input.yaml
  • plugins/jira/evals/cases/create/case-006-task-cntrlplane-plain/annotations.yaml
  • plugins/jira/evals/cases/create/case-006-task-cntrlplane-plain/input.yaml
  • plugins/jira/evals/cases/create/case-007-feature-cntrlplane/annotations.yaml
  • plugins/jira/evals/cases/create/case-007-feature-cntrlplane/input.yaml
  • plugins/jira/evals/cases/create/case-008-feature-request-rfe/annotations.yaml
  • plugins/jira/evals/cases/create/case-008-feature-request-rfe/input.yaml
  • plugins/jira/evals/cases/create/case-009-story-gcp-hcp/annotations.yaml
  • plugins/jira/evals/cases/create/case-009-story-gcp-hcp/input.yaml
  • plugins/jira/evals/cases/create/case-010-bug-ocpbugs-version-flag/annotations.yaml
  • plugins/jira/evals/cases/create/case-010-bug-ocpbugs-version-flag/input.yaml
  • plugins/jira/evals/cases/create/case-011-story-hypershift-rosa/annotations.yaml
  • plugins/jira/evals/cases/create/case-011-story-hypershift-rosa/input.yaml
  • plugins/jira/evals/cases/create/case-012-epic-gcp-hcp/annotations.yaml
  • plugins/jira/evals/cases/create/case-012-epic-gcp-hcp/input.yaml
  • plugins/jira/evals/cases/create/case-013-story-bad-summary/annotations.yaml
  • plugins/jira/evals/cases/create/case-013-story-bad-summary/input.yaml
  • plugins/jira/evals/cases/create/case-014-bug-credentials-in-content/annotations.yaml
  • plugins/jira/evals/cases/create/case-014-bug-credentials-in-content/input.yaml
  • plugins/jira/evals/eval-create.yaml

Comment on lines +17 to +19
CNTRLPLANE epic with parent linking. Tests Epic Name custom field
(customfield_10011) which must match the summary exactly. Also tests
parent linking via additional_fields.parent.key = "CNTRLPLANE-500".

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== File context =="
git ls-files 'plugins/jira/evals/cases/create/case-003-epic-cntrlplane/annotations.yaml'
wc -l plugins/jira/evals/cases/create/case-003-epic-cntrlplane/annotations.yaml
cat -n plugins/jira/evals/cases/create/case-003-epic-cntrlplane/annotations.yaml

echo
echo "== Nearby case schemas =="
fd -a 'annotations.yaml' plugins/jira/evals/cases/create | sed -n '1,40p'

echo
echo "== Search for parent-related expectations in create cases =="
rg -n --hidden --glob 'plugins/jira/evals/cases/create/**/annotations.yaml' 'expected_parent|parent\.key|parent link|parent_link|parent:' plugins/jira/evals/cases/create

Repository: openshift-eng/ai-helpers

Length of output: 3028


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Search for annotation schema consumers =="
rg -n "expected_custom_fields|expected_validation_warnings|description_template|notes|expected_parent|parent\.key|additional_fields\.parent" plugins/jira -g '!**/node_modules/**'

echo
echo "== Inspect related create cases for any parent assertion shape =="
for f in \
  plugins/jira/evals/cases/create/case-001-story-cntrlplane-basic/annotations.yaml \
  plugins/jira/evals/cases/create/case-012-epic-gcp-hcp/annotations.yaml \
  plugins/jira/evals/cases/create/case-007-feature-cntrlplane/annotations.yaml
do
  echo "--- $f ---"
  cat -n "$f"
  echo
done

Repository: openshift-eng/ai-helpers

Length of output: 13958


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Eval schema around documented fields =="
sed -n '90,130p' plugins/jira/evals/eval-create.yaml

echo
echo "== Evaluator logic around custom field checks =="
sed -n '300,380p' plugins/jira/evals/eval-create.yaml

echo
echo "== Any parent assertions anywhere in evals =="
rg -n "expected_parent|parent\.key|additional_fields\.parent|parent link|parent_link" plugins/jira/evals

Repository: openshift-eng/ai-helpers

Length of output: 6572


Assert the parent link in this case
plugins/jira/evals/cases/create/case-003-epic-cntrlplane/annotations.yaml:17-19 mentions CNTRLPLANE-500 parent linking, but the case only checks the Epic Name field. Add an explicit parent assertion or a dedicated judge for additional_fields.parent.key so that failure can’t slip through.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/jira/evals/cases/create/case-003-epic-cntrlplane/annotations.yaml`
around lines 17 - 19, Update the create-case assertions for the CNTRLPLANE epic
to explicitly validate that additional_fields.parent.key equals
"CNTRLPLANE-500", either by adding a parent assertion or a dedicated judge
alongside the existing Epic Name check.

Comment on lines +8 to +9
expected_version_field: customfield_10855
expected_version_format: array

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== fixture ==\n'
cat -n plugins/jira/evals/cases/create/case-004-story-hypershift-aro/annotations.yaml

printf '\n== search for expected_version_field / format ==\n'
rg -n "expected_version_field|expected_version_format|version 4\.22|4\.22" plugins/jira/evals -S

printf '\n== search for annotation/judge handling ==\n'
rg -n "expected_version_field|expected_version_format|normalized version|resolve.*version|version value|customfield_10855" -S .

Repository: openshift-eng/ai-helpers

Length of output: 15256


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== eval-create version check ==\n'
sed -n '280,340p' plugins/jira/evals/eval-create.yaml

printf '\n== case input ==\n'
cat -n plugins/jira/evals/cases/create/case-004-story-hypershift-aro/input.yaml

printf '\n== cntrlplane reference ==\n'
sed -n '1,120p' plugins/jira/reference/cntrlplane.md

printf '\n== related story case ==\n'
cat -n plugins/jira/evals/cases/create/case-001-story-cntrlplane-basic/annotations.yaml

Repository: openshift-eng/ai-helpers

Length of output: 7041


Assert the target version value, not just the array shape. expected_version_format: array only checks that customfield_10855 is a list, so a wrong version ID can still pass. Add the normalized openshift-4.22 expectation here, or extend the judge to resolve and compare the version value.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@plugins/jira/evals/cases/create/case-004-story-hypershift-aro/annotations.yaml`
around lines 8 - 9, The annotation only validates that customfield_10855 is an
array and does not verify the requested version. Add a normalized openshift-4.22
expectation to this case’s annotations, or update the relevant judge logic to
resolve and compare the version value while preserving the existing array-shape
check.

Comment on lines +8 to +10
expected_version_field: customfield_10855
expected_version_format: string
expected_affects_version: [{"name": "4.21"}]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make the version assertions value-sensitive.

This fixture’s notes describe customfield_10855 as openshift-4.22 and affects version as 4.21, but the executable annotations only require a string and a non-null versions field. The downstream judge therefore accepts incorrect versions. Add a machine-readable expected target-version value and compare both fields exactly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@plugins/jira/evals/cases/create/case-005-bug-ocpbugs-hypershift-rosa/annotations.yaml`
around lines 8 - 10, The annotations for this fixture only validate types and
presence, not the expected values. Update the executable assertions using
expected_version_field and expected_affects_version to require customfield_10855
to equal openshift-4.22 and the affects-version entry to exactly equal 4.21,
adding a machine-readable expected target-version value as needed.

Comment on lines +11 to +12
expected_custom_fields:
customfield_10028: 2.0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Assert the expected Story Points value, not just field presence.

expected_custom_fields declares customfield_10028: 2.0, but the downstream convention_fields_applied judge only verifies that the field exists. An estimate of 1 or 8 would pass, so this case does not actually test the documented two-point smart default. Compare the generated value with the annotation, with numeric normalization if necessary.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/jira/evals/cases/create/case-009-story-gcp-hcp/annotations.yaml`
around lines 11 - 12, The convention_fields_applied judge must validate the
value of customfield_10028, not merely its presence. Update the relevant
comparison logic to read the expected value from expected_custom_fields and
compare it with the generated field using numeric normalization so equivalent
numeric representations pass while incorrect estimates fail.

Comment on lines +17 to +20
GCP project epic with GCP-HCP team conventions. Tests Epic Name custom
field (customfield_10011) matching summary, and GCP epic template (use
case/context, current/desired state, scope, story breakdown, acceptance
criteria). No story points on epics.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== target file =="
cat -n plugins/jira/evals/cases/create/case-012-epic-gcp-hcp/annotations.yaml

echo
echo "== search for story point mentions in eval cases =="
rg -n --hidden --glob 'plugins/jira/evals/cases/**/annotations.yaml' -e 'story points|story_points|storyPoints|no story points|points' plugins/jira/evals/cases

echo
echo "== search for forbidden/absent field conventions in eval cases =="
rg -n --hidden --glob 'plugins/jira/evals/cases/**/annotations.yaml' -e 'forbidden|must not|must_not|absent|should not|should_not|not emitted|not present|missing field' plugins/jira/evals/cases

Repository: openshift-eng/ai-helpers

Length of output: 1335


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files that define or consume annotations.yaml =="
rg -n --hidden -e 'expected_custom_fields|expected_validation_warnings|description_template|notes:' plugins/jira -g '*.py' -g '*.ts' -g '*.js' -g '*.yaml' -g '*.yml'

echo
echo "== search for any schema around annotations fields =="
rg -n --hidden -e 'expected_issue_type|expected_project_key|expected_conventions|expected_labels|expected_validation_warnings|expected_creation_blocked' .

echo
echo "== search for forbidden/negative assertions in jira eval code =="
rg -n --hidden -e 'forbidden|must not|must_not|absent|not emitted|missing field|negative assertion|unexpected field|not present' plugins/jira

Repository: openshift-eng/ai-helpers

Length of output: 18422


Make the no-story-points rule machine-checkable. The note only lives in notes; add an explicit assertion or a forbidden-field check so epics fail when story points are present.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/jira/evals/cases/create/case-012-epic-gcp-hcp/annotations.yaml`
around lines 17 - 20, Make the no-story-points requirement machine-checkable in
the epic evaluation annotations: add an explicit assertion or forbidden-field
check alongside the existing template and custom-field checks, targeting the
story-points field so the case fails whenever an epic contains story points.

Comment on lines +41 to +49
Also write `validation-results.json` with:
{
"summary_warnings": [...],
"security_warnings": [...],
"creation_blocked": false
}

If security validation detects credentials, set creation_blocked to
true and leave planned-call.json empty (write {} only).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Assert the complete validation output contract.

The configuration requires both output files, but no judge requires validation-results.json or compares its warnings with expected_validation_warnings. Additionally, blocked cases pass this judge with any parseable JSON, not specifically {}. Require both files, validate their schemas, compare expected warnings, and require creation_blocked: true for blocked cases.

Also applies to: 109-117, 126-164

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/jira/evals/eval-create.yaml` around lines 41 - 49, The eval
assertions must enforce the complete validation output contract. Update the
relevant judge logic to require both validation-results.json and
planned-call.json, validate validation-results.json fields and types, compare
summary_warnings and security_warnings against expected_validation_warnings, and
require creation_blocked to be true for credential-detected cases while
planned-call.json is exactly {}.

Comment on lines +160 to +164
required = ["projectKey", "issueTypeName", "summary", "contentFormat"]
missing = [f for f in required if f not in data]
if missing:
return (False, f"Missing required fields: {', '.join(missing)}")
return (True, "Valid JSON with all required fields")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Validate all required createJiraIssue fields.

The prompt’s contract includes cloudId, description, and additional_fields, but this judge only requires four fields. A malformed MCP call can therefore pass the structural gate.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/jira/evals/eval-create.yaml` around lines 160 - 164, The validation
logic for the createJiraIssue judge must enforce every field in the prompt
contract. Update the required fields list in the validation block to include
cloudId, projectKey, issueTypeName, summary, description, contentFormat, and
additional_fields, so malformed calls cannot pass the structural gate.

Comment on lines +294 to +321
# Check version format
exp_vf = ann.get("expected_version_format")
if exp_vf:
tv = af.get("customfield_10855", data.get("customfield_10855"))
if tv is None:
errors.append("customfield_10855 (Target Version) not set")
elif exp_vf == "array" and not isinstance(tv, list):
errors.append(f"Target Version should be array, got {type(tv).__name__}: {tv}")
elif exp_vf == "string" and not isinstance(tv, str):
errors.append(f"Target Version should be string, got {type(tv).__name__}: {tv}")
else:
details.append(f"version_format={exp_vf}")
# Check affects version (OCPBUGS bugs)
exp_av = ann.get("expected_affects_version")
if exp_av:
vers = af.get("versions", data.get("versions"))
if vers is None:
errors.append("versions (Affects Version) not set")
else:
details.append(f"affects_version set")
# Check custom fields
exp_cf = ann.get("expected_custom_fields", {})
for field_id, expected_val in exp_cf.items():
actual_val = af.get(field_id, data.get(field_id))
if actual_val is None:
errors.append(f"Custom field {field_id} not set")
else:
details.append(f"{field_id} set")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Compare convention values, not only their presence or type.

expected_affects_version is only checked for non-null, expected_custom_fields ignores expected_val, and version validation accepts any list/string without checking item shape, normalization, or expected_version_field. Incorrect Jira fields can pass the structural judge.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/jira/evals/eval-create.yaml` around lines 294 - 321, The validation
logic in the eval’s version, affects-version, and custom-field checks only
verifies presence or broad type, not expected values. Update the relevant checks
to honor expected_affects_version, compare each expected_custom_fields entry
against its expected_val, validate version item shape and normalized values, and
use expected_version_field when selecting the version field; preserve clear
errors and details for mismatches.

Comment on lines +340 to +385
prompt: |
You are evaluating whether a Jira issue description follows the correct
type-specific template from the jira:create skill.

The planned createJiraIssue call:

{% for path, content in outputs.files.items() if path.endswith('planned-call.json') %}
{{ content }}
{% endfor %}

Expected outcomes for this test case:

{{ annotations }}

The 'description_template' field indicates which template the description
should follow. Key template requirements:

- **story**: User story format (As a / I want / so that), acceptance criteria
- **bug**: Problem description, version, reproducibility, steps to reproduce,
actual results, expected results
- **epic**: Objective, scope, acceptance criteria (3-6 outcomes), Epic Name field
- **feature**: Market problem, strategic value, success criteria
- **task**: What/why, acceptance criteria, technical details
- **feature-request**: Title, nature/description, business requirements
- **gcp-story**: GCP team template — user story format, context/background,
requirements, technical approach, dependencies, acceptance criteria checklist
- **gcp-epic**: GCP template — use case/context, current/desired state, scope,
story breakdown, acceptance criteria

Evaluate on a 1-5 scale:

Score 1: No description, or description is a single line with no structure.
Score 2: Some structure but wrong template — e.g., a bug using story format,
or missing most required sections for the correct template.
Score 3: Correct template identified and partially followed — has some required
sections but is missing important ones (e.g., story without AC, bug
without steps to reproduce).
Score 4: Correct template fully followed with all required sections present.
Content is specific to the summary/context provided.
Score 5: Excellent — correct template, all sections present with specific and
actionable content, well-formatted Markdown.

If creation_blocked is true in annotations, evaluate only whether the skill
correctly identified the security issue — score 4 for correct detection,
5 for detection with helpful guidance about what was found.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Provide validation evidence to the blocked-case LLM judge.

For blocked cases, the rubric scores detection and helpful guidance, but the prompt supplies only planned-call.json and annotations—not validation-results.json, where the warning and guidance are written. Include the validation output or make this assertion deterministic.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/jira/evals/eval-create.yaml` around lines 340 - 385, The blocked-case
evaluation prompt lacks the validation evidence needed to assess detection and
guidance. Update the prompt’s planned-call section to also load and display
validation-results.json from the outputs, so the judge can verify the warning
and guidance; retain the existing annotations and rubric.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant