Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion hyperfleet-devtools/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hyperfleet-devtools",
"version": "0.5.0",
"version": "0.5.1",
"description": "Development assistance tools for HyperFleet - commit message generation, architecture impact analysis, E2E test case design, E2E test automation, and more",
"author": {
"name": "HyperFleet Team",
Expand Down
2 changes: 1 addition & 1 deletion hyperfleet-devtools/skills/architecture-impact/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: architecture-impact
description: Analyzes code changes in HyperFleet component repositories (API, Sentinel, Adapter, Broker) to determine if architecture documentation needs updates using directory-based scope and complete document reading with single comprehensive LLM analysis. Activates when users ask "analyze architecture impact", "check if docs need update", or use /architecture-impact.
description: Analyzes code changes in HyperFleet component repositories (API, Sentinel, Adapter, Broker) to determine if architecture documentation needs updates using directory-based scope and complete document reading with single comprehensive LLM analysis. Activates when users ask "analyze architecture impact", "check if docs need update", or use /architecture-impact. Note - this skill operates on code repositories, not JIRA components. For the full list of valid JIRA components, see ticket-hygiene.md in the architecture repo.
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.

The description field drives skill triggering. Adding "JIRA components" and "ticket-hygiene.md" here could cause false triggers when users talk about JIRA. This clarification would be better placed in the skill body instead of the frontmatter description.

---

# Architecture Impact Analyzer
Expand Down
2 changes: 1 addition & 1 deletion hyperfleet-jira/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hyperfleet-jira",
"version": "0.5.2",
"version": "0.5.3",
"description": "JIRA integration for HyperFleet team - sprint management, task tracking, ticket creation, triage, and story point estimation",
"author": {
"name": "Ciaran Roche",
Expand Down
17 changes: 10 additions & 7 deletions hyperfleet-jira/commands/triage.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ Audit JIRA tickets for sprint readiness, including required fields, valid compon

## Instructions

0. **Fetch ticket-hygiene standard (source of truth for field validation):**
```bash
curl -sL https://raw.githubusercontent.com/openshift-hyperfleet/architecture/main/hyperfleet/standards/ticket-hygiene.md 2>/dev/null
```
Extract the valid components list and activity types from the fetched document. Use them for all validation steps below. Do NOT use hardcoded values.

1. **Get tickets to audit (current sprint by default):**
```bash
jira sprint list --current -p HYPERFLEET --raw 2>/dev/null
Expand All @@ -41,15 +47,12 @@ Audit JIRA tickets for sprint readiness, including required fields, valid compon
jira issue list -q"project = HYPERFLEET AND sprint in openSprints() AND description is EMPTY" --plain 2>/dev/null
```

5. **Find tickets without valid components (must be Adapter, API, Architecture, or Sentinel):**
5. **Find tickets without valid components:**
```bash
jira issue list -q"project = HYPERFLEET AND component is EMPTY AND sprint in openSprints()" --plain 2>/dev/null
```

Also check for invalid components:
```bash
jira issue list -q"project = HYPERFLEET AND sprint in openSprints() AND component not in (Adapter, API, Architecture, Sentinel)" --plain 2>/dev/null
```
Also check for invalid components — build the JQL `component not in (...)` clause dynamically using the component names fetched from ticket-hygiene.md in step 0. Quote multi-word names with single quotes in JQL (e.g., `'Claude Plugins'`).

Comment thread
coderabbitai[bot] marked this conversation as resolved.
6. **Find tickets without Activity Type:**
```bash
Expand Down Expand Up @@ -115,7 +118,7 @@ Audit JIRA tickets for sprint readiness, including required fields, valid compon
| TICKET-1 | [Summary] | None |
| TICKET-2 | [Summary] | InvalidComponent |

**Valid Components:** Adapter, API, Architecture, Sentinel
**Valid Components:** [list from ticket-hygiene.md fetched in step 0]

**Action Required:** Assign valid component for tracking.

Expand All @@ -126,7 +129,7 @@ Audit JIRA tickets for sprint readiness, including required fields, valid compon
|--------|---------|------|
| TICKET-1 | [Summary] | Story |

**Valid Activity Types:** Associate Wellness & Development, Incidents & Support, Security & Compliance, Quality / Stability / Reliability, Future Sustainability, Product / Portfolio Work
**Valid Activity Types:** [list from ticket-hygiene.md fetched in step 0]

**Action Required:** Set Activity Type for capacity planning.

Expand Down
6 changes: 5 additions & 1 deletion hyperfleet-jira/skills/jira-story-pointer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ Activate this skill when the user:

## Story Point Scale Reference

HyperFleet uses a modified Fibonacci sequence for story points:
HyperFleet uses a modified Fibonacci sequence for story points. The authoritative source is **ticket-hygiene.md** in the architecture repo. The scale below should match. If in doubt, fetch the latest:

```bash
curl -sL https://raw.githubusercontent.com/openshift-hyperfleet/architecture/main/hyperfleet/standards/ticket-hygiene.md 2>/dev/null
```

| Points | Meaning | Typical Scope | Notes |
|--------|---------|---------------|-------|
Expand Down
26 changes: 26 additions & 0 deletions hyperfleet-jira/skills/jira-ticket-creator/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ All JIRA ticket content — summaries, descriptions, comments, and acceptance cr

The `jira-cli` accepts **Markdown** and converts it to ADF (Atlassian Document Format) for JIRA Cloud. Standard Markdown works correctly — headers, bullets, bold, inline code, fenced code blocks, links, and curly braces all render as expected.

## Authoritative Source

Field requirements, valid components, activity types, and story point scales are defined in **ticket-hygiene.md** in the architecture repo. Before creating tickets, fetch the current standard:

```bash
curl -sL https://raw.githubusercontent.com/openshift-hyperfleet/architecture/main/hyperfleet/standards/ticket-hygiene.md 2>/dev/null
```

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.

This section says not to rely on hardcoded values, but the story point scale (0, 1, 3, 5, 8, 13) shows up in two places below (section 4 and Step 4) without referencing ticket-hygiene.md. jira-story-pointer handles this well by keeping the inline values but adding "The scale below should match. If in doubt, fetch the latest." Same treatment here would keep things consistent.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed — the hardcoded Activity Types list in the triage output template now references ticket-hygiene.md, same as Components. See 223893e.

Use the fetched document as the source of truth for valid components, activity types, and story point scales. Do NOT rely on hardcoded values.

## References

Load these files as needed:
Expand Down Expand Up @@ -165,6 +175,22 @@ All fields can be set via CLI during creation:
- **Add Component**: use `-C ComponentName`
- **Code blocks**: use fenced code blocks (triple backticks) in the description — they render correctly via CLI

#### Issue Links (Blocks / Is Blocked By)

When linking tickets with "Blocks" relationships, the argument order is critical:

```bash
jira issue link <OUTWARD-TICKET> <INWARD-TICKET> "Blocks"
```

This means: `OUTWARD-TICKET` **blocks** `INWARD-TICKET`.

Examples:
- New ticket blocks an existing one: `jira issue link HYPERFLEET-NEW HYPERFLEET-EXISTING "Blocks"`
- New ticket is blocked by an existing one: `jira issue link HYPERFLEET-EXISTING HYPERFLEET-NEW "Blocks"`

**Common mistake:** Swapping the arguments inverts the link direction — the parent ticket appears as "IS BLOCKED BY" instead of "BLOCKS".

### Step 9: Verify and Return Details

```bash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Activity Type is **required** for sprint/kanban capacity planning. Tickets without an Activity Type appear as "Uncategorized" and cannot be properly allocated.

The authoritative source for activity types is **ticket-hygiene.md** in the architecture repo. The values below should match. If in doubt, fetch the latest version:

```bash
curl -sL https://raw.githubusercontent.com/openshift-hyperfleet/architecture/main/hyperfleet/standards/ticket-hygiene.md 2>/dev/null
```

Set via CLI: `--custom activity-type="<value>"`

## Assignment Flow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,18 @@ Explanation of business value and impact.
- Criterion 3
```

## Linking Tickets (Blocks Relationship)

```bash
# NEW_TICKET blocks EXISTING_TICKET
jira issue link HYPERFLEET-NEW HYPERFLEET-EXISTING "Blocks"

# EXISTING_TICKET blocks NEW_TICKET (new ticket is blocked by existing)
jira issue link HYPERFLEET-EXISTING HYPERFLEET-NEW "Blocks"
```

The first argument is always the outward (blocking) ticket. Getting the order wrong inverts the link direction.

## Important Reminders

- Fenced code blocks (triple backticks) work correctly via CLI
Expand Down
13 changes: 13 additions & 0 deletions hyperfleet-jira/skills/jira-ticket-creator/references/pitfalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
1. Use `--body-file` flag — it doesn't exist! Use `-b "$(cat /tmp/file.txt)"` instead
2. Use raw field IDs like `--custom customfield_10028=3` — silently ignored! Use aliases
3. Use JIRA wiki markup for links (`[text|url]`) — the `jira-cli` expects Markdown (`[text](url)`) and wiki markup renders as malformed, duplicated links
4. Swap arguments in `jira issue link` — the first argument is the OUTWARD ticket (the one that "blocks"), the second is the INWARD ticket (the one that "is blocked by"). Wrong order inverts the link direction

### DO

Expand Down Expand Up @@ -52,6 +53,18 @@ jira issue create --project HYPERFLEET --type Story \

**Solution:** Use the exact syntax with quotes: `--custom activity-type="Quality / Stability / Reliability"`. Use field aliases, never raw IDs.

### Issue: Link Direction Inverted (Blocks vs Is Blocked By)

**Symptom:** After `jira issue link`, the parent ticket shows "IS BLOCKED BY" the new ticket instead of "BLOCKS" it.

**Solution:** The argument order matters — first argument is the outward (blocking) ticket:

```bash
jira issue link BLOCKER-TICKET BLOCKED-TICKET "Blocks"
```

This creates: `BLOCKER-TICKET` blocks `BLOCKED-TICKET`.

### Issue: Description is Empty After Creation

**Solution:** Sometimes `-b "$(cat ...)"` fails silently. Verify with `jira issue view HYPERFLEET-XXX --plain`. If empty, set via pipe:
Expand Down
28 changes: 17 additions & 11 deletions hyperfleet-jira/skills/jira-triage/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,25 @@ Activate when the user:

## Triage Checklist

### Authoritative Source

Field requirements, valid components, activity types, and story point scales are defined in **ticket-hygiene.md** in the architecture repo. Before triaging, fetch the current standard:

```bash
curl -sL https://raw.githubusercontent.com/openshift-hyperfleet/architecture/main/hyperfleet/standards/ticket-hygiene.md 2>/dev/null
```

Use the fetched document as the source of truth for all validation in this skill. Do NOT rely on hardcoded values.

Comment on lines +30 to +37
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail fast on standards fetch; don’t silently continue with unknown validation source.

The current curl ... 2>/dev/null flow can fail silently and still allow triage logic to continue without authoritative rules. Make this step explicit and blocking (check exit code/content), and prefer a pinned ref (tag/commit SHA) to avoid non-deterministic behavior from main.

Suggested doc update
-```bash
-curl -sL https://raw.githubusercontent.com/openshift-hyperfleet/architecture/main/hyperfleet/standards/ticket-hygiene.md 2>/dev/null
-```
+```bash
+HYGIENE_URL="https://raw.githubusercontent.com/openshift-hyperfleet/architecture/<PINNED_REF>/hyperfleet/standards/ticket-hygiene.md"
+ticket_hygiene="$(curl -fsSL "$HYGIENE_URL")" || {
+  echo "Failed to fetch ticket-hygiene.md from architecture repo" >&2
+  exit 1
+}
+[ -n "$ticket_hygiene" ] || { echo "ticket-hygiene.md is empty" >&2; exit 1; }
+```

As per coding guidelines, "Apply these language-agnostic code review checks from HyperFleet standards ... Security (SEC-01 to SEC-03) ... Validate input at system boundaries."

🤖 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 `@hyperfleet-jira/skills/jira-triage/SKILL.md` around lines 30 - 37, Replace
the current silent curl fetch with a failing, explicit fetch: introduce a
HYGIENE_URL variable (use a pinned ref/tag/commit instead of main), fetch into a
ticket_hygiene variable using a curl invocation that fails on HTTP errors, check
the command exit status and that ticket_hygiene is non-empty, and if either
check fails emit a clear stderr error and exit non-zero so triage does not
proceed without the authoritative ticket-hygiene.md.

### Required Fields (Must Have)
| Field | Requirement |
|-------|-------------|
| Title | Clear, actionable, under 100 characters |
| Description | Detailed context (recommend > 100 characters) |
| Acceptance Criteria | At least 2 clear, testable criteria |
| Story Points | Set (scale: 0, 1, 3, 5, 8, 13) |
| Component | One of: Adapter, API, Architecture, Sentinel |
| Activity Type | Set for capacity planning |
| Story Points | Per scale defined in ticket-hygiene.md |
| Component | Must match a valid component from ticket-hygiene.md |
| Activity Type | Must match a valid activity type from ticket-hygiene.md |

### Recommended Fields
| Field | Requirement |
Expand All @@ -53,11 +63,7 @@ Activate when the user:

## Components

Valid components for HYPERFLEET project:
- **Adapter** - Integration adapters
- **API** - API services
- **Architecture** - Architecture decisions and documentation
- **Sentinel** - Background processing services
Valid components are defined in the "Valid Components" section of ticket-hygiene.md (fetched above). Validate the ticket's component against that list.

## How to Check a Ticket

Expand Down Expand Up @@ -88,7 +94,7 @@ When analyzing a ticket, provide:
| Description | PASS/FAIL | [Length: X chars] |
| Acceptance Criteria | PASS/FAIL | [Count: X criteria] |
| Story Points | PASS/FAIL | [Value or "Missing"] |
| Component | PASS/FAIL | [Must be: Adapter, API, Architecture, or Sentinel] |
| Component | PASS/FAIL | [Must be a valid project component — see Components section] |
| Activity Type | PASS/FAIL | [Type or "Uncategorized"] |

#### Overall Score: X/6 Required Checks Passed
Expand All @@ -104,7 +110,7 @@ When analyzing a ticket, provide:

## Activity Types

Follow the same activity type definitions used by the `jira-ticket-creator` skill. When triaging, verify the ticket's activity type is set and matches the correct Sankey tier (Non-Negotiable → Core Principles → Balance).
Activity types and their tier assignments (Non-Negotiable → Core Principles → Balance) are defined in the "Activity Types" section of ticket-hygiene.md (fetched above). Validate the ticket's activity type against that list.

## Red Flags to Highlight

Expand All @@ -115,7 +121,7 @@ Follow the same activity type definitions used by the `jira-ticket-creator` skil
- Vague titles like "Fix bug" or "Update feature"
- Tickets open > 30 days without progress
- **Missing Activity Type** (appears as Uncategorized in capacity planning)
- **Invalid Component** (must be Adapter, API, Architecture, or Sentinel)
- **Invalid Component** (must be a valid project component — see Components section)

## Integration with Commands

Expand Down
2 changes: 1 addition & 1 deletion hyperfleet-work-triage/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hyperfleet-work-triage",
"version": "0.2.0",
"version": "0.2.1",
"description": "Work triage skills for HyperFleet: /bugs-triage for interactive JIRA bug and GitHub issue triage. /open-prs surfaces and prioritizes open PRs across the org using GitHub + JIRA context with multi-factor scoring and confidence levels.",
"author": {
"name": "Rafael Benevides",
Expand Down
12 changes: 11 additions & 1 deletion hyperfleet-work-triage/skills/bugs-triage/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ Load these files as needed during triage:
- `references/owners.csv` — Component/domain owners for assignee suggestions
- `../../references/github-repos.md` — GitHub repositories in triage scope (skip issues from unlisted repos)

## Ticket Hygiene Standard

Before triaging, fetch the current field requirements (valid components, activity types, story points):

```bash
curl -sL https://raw.githubusercontent.com/openshift-hyperfleet/architecture/main/hyperfleet/standards/ticket-hygiene.md 2>/dev/null
```

Use the fetched document as the source of truth for component validation. Do NOT rely on hardcoded component lists.

## Ticket Creation

When creating JIRA tickets (e.g., from accepted GitHub issues or RFE conversions), use the `hyperfleet-jira:jira-ticket-creator` skill via the Skill tool. This skill handles description formatting, Activity Type classification, Story Points estimation, and all ticket creation best practices. Pass the issue context (title, description, component, suggested priority) as the skill argument.
Expand Down Expand Up @@ -85,7 +95,7 @@ Evaluate and present:
|-------|--------|-------|
| Sufficient info/logs | PASS/FAIL | Logs, steps to reproduce, environment details? |
| Priority set correctly | PASS/FAIL/MISSING | Based on SLA table |
| Component identified | PASS/FAIL/MISSING | Must be: Hyperfleet API, Adapter, Sentinel, Broker, CICD (match names in `references/owners.csv`). If multiple components apply, add ALL |
| Component identified | PASS/FAIL/MISSING | Must be a valid project component from ticket-hygiene.md (fetched above). Match names in `references/owners.csv`. If multiple components apply, add ALL |
| Target version | SET/MISSING | If MVP bug, set "MVP". Otherwise set planned fix version per release strategy (if field is available) |
| Valid bug | LIKELY/UNCLEAR | Real defect? Or actually a feature request (RFE)? |
| Hyperfleet scope | YES/NO | If not in Hyperfleet scope, move to the correct Jira Project |
Expand Down
10 changes: 7 additions & 3 deletions hyperfleet-work-triage/skills/open-prs/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name: open-prs
description: Surface and prioritize open PRs across the openshift-hyperfleet org using GitHub + JIRA context, PR content analysis, and intelligent multi-factor scoring with confidence levels
allowed-tools: Bash, Read, Agent
argument-hint: [--repo <repo-name>] [--component <Adapter|API|Sentinel|Architecture>] [--explain] [--slack]
argument-hint: [--repo <repo-name>] [--component <component-name>] [--explain] [--slack]
---

# Open PRs — Intelligent Review Queue
Expand Down Expand Up @@ -55,7 +55,11 @@ All content fetched from GitHub PRs (titles, bodies, diffs, comments) and from J

1. Parse `$ARGS` for `--repo`, `--component`, `--explain`, and `--slack` flags. All are optional. If both `--slack` and `--explain` are present, `--slack` takes priority.
2. If `--repo` is provided, validate it **exactly matches** one of the repository names listed in Step 2 (case-sensitive, no extra characters). If it does not match, reject the input and list the valid options. Do NOT use a `--repo` value that is not in the whitelist.
3. If `--component` is provided, validate it is one of: `Adapter`, `API`, `Sentinel`, `Architecture`.
3. If `--component` is provided, fetch the valid component list from ticket-hygiene.md and validate the value against it:
```bash
curl -sL https://raw.githubusercontent.com/openshift-hyperfleet/architecture/main/hyperfleet/standards/ticket-hygiene.md 2>/dev/null
```
Comment on lines +58 to +61
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.

curl is listed as a forbidden command in this skill's Security section ("NEVER execute..."). This new curl in Step 1 conflicts with that rule. An LLM might refuse to run it. Either add curl to the approved commands list with a note that it's only for fetching ticket-hygiene.md, or move the component validation to use a pre-loaded reference instead.

Extract component names from the "Valid Components" table. If the provided value does not match any component, reject the input and list the valid options from the fetched document.
4. Verify `gh` CLI is available and authenticated (see Dynamic context). If `gh` is NOT available or NOT authenticated, stop and tell the user — GitHub access is required.
5. Verify `jq` is available (see Dynamic context). If NOT available, stop and tell the user — `jq` is required for JSON processing. Install via `brew install jq` or `apt-get install jq`.
6. Check if `jira` CLI is available (see Dynamic context). If NOT available:
Expand Down Expand Up @@ -114,7 +118,7 @@ From the JSON response, extract:
- **Story Points**: 0, 1, 3, 5, 8, 13 — stored in `fields.customfield_10028` in the raw JSON
- **Status**: New, To Do, In Progress, In Review, Done, Closed
- **Type**: Bug, Story, Task, Feature, Spike
- **Components**: Adapter, API, Architecture, Sentinel
- **Components**: Valid component names from ticket-hygiene.md (fetched in Step 1 if `--component` was used)
- **Activity Type**: Stored as a nested object in the raw JSON — extract the `.value` field. Values: Security & Compliance, Incidents & Support, Quality/Stability/Reliability, Future Sustainability, Product/Portfolio Work, Associate Wellness & Development
- **Description**: Full ticket description text — read this to understand actual urgency and context
- **Linked issues**: Blocking/blocked-by relationships from `issuelinks` in the raw JSON. Each link has a `type.name` (e.g., "Blocks") and either `outwardIssue` or `inwardIssue`. For "Blocks" type: if the other ticket appears as `inwardIssue`, then the CURRENT ticket blocks it. If it appears as `outwardIssue`, the CURRENT ticket is blocked by it.
Expand Down