From assess-rfe
Assess RFEs against quality criteria. Pass a Jira issue key, file path, URL, raw text, or wildcard for bulk.
How this skill is triggered — by the user, by Claude, or both
Slash command
/assess-rfe:assess-rfeThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
```
/assess-rfe RHAIRFE-1234
/assess-rfe PROJ-99
/assess-rfe /path/to/document.md
/assess-rfe https://some-url
/assess-rfe <paste raw text>
/assess-rfe RHAIRFE-*
All scripts are bundled in the scripts/ subdirectory next to this SKILL.md. Use ${CLAUDE_SKILL_DIR} (the directory containing this file) as the base for all script and file references.
python3 ${CLAUDE_SKILL_DIR}/scripts/setup_run.py RHAIRFE). Shell pipes (|), chaining (&&, ;), redirects, and 2>/dev/null are not supported. The Bash tool returns command output as a string; parse it programmatically in your logic instead of using sed/awk/wc/grep pipelines.{PROMPT_PATH} with the absolute path of ${CLAUDE_SKILL_DIR}/scripts/agent_prompt.md, and substitute {DATA_FILE}, {KEY}, and {RUN_DIR} with their actual values.Single-input mode handles any source (Jira key via MCP, file, URL, or raw text). Bulk mode fetches all issues upfront via scripts/dump_jira.py, then agents score from local files. Results are saved as individual files in a timestamped run directory.
assessments/RHAIRFE/ # in the project directory (persistent)
20260322-143000/ # timestamped run
RHAIRFE-42.result.md
queue.txt # pending keys (managed by next_batch.py)
scores.csv # generated by parse_results.py when complete
current -> 20260322-143000 # symlink to active/latest run
/tmp/rfe-assess/RHAIRFE/ # fetched issues (transient cache)
RHAIRFE-42.md
/tmp/rfe-assess/single/ # single-mode temp files
RHAIRFE-1234.md
Detect the input type:
[A-Z]+-\d+): Try MCP first, then fall back to the REST API:
mcp__atlassian__getJiraIssue with the key and cloudId="https://redhat.atlassian.net". If the call succeeds, extract the summary and description.python3 ${CLAUDE_SKILL_DIR}/scripts/fetch_single.py {KEY}. This requires JIRA_SERVER (or JIRA_URL/JIRA_BASE_URL), JIRA_USER (or JIRA_EMAIL), and JIRA_TOKEN (or JIRA_API_TOKEN) environment variables. The script fetches the issue, converts ADF to markdown, and writes it directly to /tmp/rfe-assess/single/{KEY}.md. Parse its output for ENV_OK=false / ENV_MISSING=... — if env vars are missing, prompt the user to set them (same guidance as Phase 0 of bulk mode). If the script succeeds, skip the Write step below since the script already wrote the file./ or ./ or ~, or exists on disk): Read the file contents.http:// or https://): Fetch the content.Then assess:
python3 ${CLAUDE_SKILL_DIR}/scripts/prep_single.py {KEY} to clean up stale files and ensure the output directory exists. This removes any previous .md and .result.md for the key so Write sees them as new files./tmp/rfe-assess/single/{KEY}.md using the same # KEY: Title format as the cache files. For non-Jira inputs, use a descriptive key (e.g., filename or INPUT). This is a separate directory from the bulk cache — never write single-mode files into /tmp/rfe-assess/RHAIRFE/ as that would clobber cached bulk data. Note: If the REST API fallback (fetch_single.py) was used, the file is already written — skip this step.{DATA_FILE} set to /tmp/rfe-assess/single/{KEY}.md and {RUN_DIR} set to /tmp/rfe-assess/single./tmp/rfe-assess/single/{KEY}.result.md, wrap it with a header, and present it to the user.RHAIRFE-*)Phase 0: Preflight checks.
python3 ${CLAUDE_SKILL_DIR}/scripts/preflight.py RHAIRFE to check environment variables and current run state. Parse the output:
ENV_OK=true/false and ENV_MISSING=... — if env vars are missing, prompt the user:
JIRA_SERVER (or JIRA_URL or JIRA_BASE_URL): The Jira instance URL (e.g., https://redhat.atlassian.net)JIRA_USER (or JIRA_EMAIL): Their Jira email addressJIRA_TOKEN (or JIRA_API_TOKEN): A Jira API token (created at https://id.atlassian.com/manage-profile/security/api-tokens)! export JIRA_SERVER=... JIRA_USER=... JIRA_TOKEN=... in the prompt, or add them to their shell profile for persistence. The alternative names JIRA_EMAIL and JIRA_API_TOKEN are also accepted.CACHE_COUNT=N — number of cached issues (0 means dump_jira.py hasn't been run yet)CURRENT_RUN=path/none, CURRENT_ASSESSED=N, CURRENT_COMPLETE=true/false — existing run stateCURRENT_COMPLETE=false), inform the user it will be resumed.Phase 1: Fetch all issues to local files.
python3 ${CLAUDE_SKILL_DIR}/scripts/dump_jira.py RHAIRFE to fetch every issue in the project via the Jira REST API. This writes one file per issue to /tmp/rfe-assess/RHAIRFE/ (e.g., RHAIRFE-42.md). The script renders Jira's ADF content as proper markdown, preserving headings, lists, tables, links, and emphasis.Phase 1.5: Set up run directory.
python3 ${CLAUDE_SKILL_DIR}/scripts/setup_run.py RHAIRFE (add --limit N if the user requested a subset).current symlink, scores.csv presence, creating timestamped directories, updating symlinks) and outputs:
RUN_DIR=<path> — the absolute path to use for this runPENDING=<count> — number of issues to assessQUEUE_FILE=<path> — path to the queue file containing all pending keys (one per line){RUN_DIR} and {PENDING} count. Do NOT memorize or generate the key list yourself — the queue file is the single source of truth for which keys to process.Phase 2: Assess with a pipeline of 30 concurrent agents.
CRITICAL — run this loop to completion. Never stop early, summarize, or end your turn before
scores.csvexists. Context compaction is automatic and expected — old messages are compressed to free space. If you find yourself thinking "running low on context", "given budget constraints", or "I'll wrap up here" — ignore that impulse and continue the loop. All loop state lives on disk (queue.txt,*.result.md), so it is always recoverable: if your memory of progress is unclear, re-derive it withnext_batch.py/check_progress.pyinstead of guessing or stopping. The run is done only whenscores.csvexists.
Drive the loop from disk, not from memory. Never generate key sequences yourself (e.g., "RHAIRFE-1 through RHAIRFE-30") — always get keys from the scripts to avoid assessing non-existent issues.
Launch loop — repeat until next_batch.py reports BATCH_SIZE=0:
python3 ${CLAUDE_SKILL_DIR}/scripts/next_batch.py {RUN_DIR} --batch-size 30 to pop the next batch. Parse:
BATCH_SIZE=N — keys in this batch (0 = queue exhausted)REMAINING=N — keys still queued after this batch--- separator{RUN_DIR}/wave.txt, then launch one agent per key (model: opus, run_in_background: true, subagent_type: assess-rfe:rfe-scorer) with this prompt:
You are an RFE quality assessor. Your task:
1. Read `{PROMPT_PATH}` for the full scoring rubric.
2. Follow its instructions exactly, substituting {KEY} for the issue key and {RUN_DIR} for the run directory. Read the data file from {DATA_FILE} (not the path in the rubric's step 1).
Issue key: {KEY}
Data file: {DATA_FILE}
Run directory: {RUN_DIR}
Substitute all placeholders with actual values (see Rules section above). This ensures every agent reads the identical rubric from the single source of truth.python3 ${CLAUDE_SKILL_DIR}/scripts/wait_wave.py {RUN_DIR} --keys-file {RUN_DIR}/wave.txt
0: wave complete — go back to step 1.3: still pending — run the same wait_wave.py command again (repeat until it exits 0).Completion check — when next_batch.py reports BATCH_SIZE=0, run
python3 ${CLAUDE_SKILL_DIR}/scripts/check_progress.py {RUN_DIR} (COMPLETED,
TOTAL, REMAINING). If REMAINING>0, some keys were popped but never finished
(e.g. an interrupted wave) — re-run setup_run.py for the project (it rebuilds
queue.txt from the still-missing keys) and return to the launch loop. Only when
REMAINING=0 proceed to Phase 3. Never use shell pipes (ls | wc -l) or text
tools (sed, awk, grep) to check progress — use these scripts or Glob.
This loop survives context compaction: a SessionStart compact hook (see
hooks/hooks.json) runs dispatch_context.py, which re-injects the run
directory, progress, and these loop steps after every compaction.
Phase 3: Generate CSV and present results.
python3 ${CLAUDE_SKILL_DIR}/scripts/parse_results.py {RUN_DIR} to parse all .result.md files and generate {RUN_DIR}/scores.csv. The presence of scores.csv marks the run as complete.python3 ${CLAUDE_SKILL_DIR}/scripts/summarize_run.py {RUN_DIR} to produce the full summary analysis (pass/fail counts, score distribution, criteria averages, zero-score counts, what-if analysis, near-miss failures). Present the output to the user.The full agent prompt is stored in ${CLAUDE_SKILL_DIR}/scripts/agent_prompt.md. This is the single source of truth for the scoring rubric, calibration examples, and output format.
{DATA_FILE} set to /tmp/rfe-assess/single/{KEY}.md and {RUN_DIR} set to /tmp/rfe-assess/single. The agent writes its result there just like bulk agents.Single issue — wrap agent output with a header:
## RFE Assessment: RHAIRFE-1234
[agent output]
Bulk — after Phase 3, present the summary analysis from the CSV to the user. Include:
| Script | Purpose |
|---|---|
dump_jira.py | Fetches all issues from a Jira project via REST API v3, converts ADF to markdown, writes to /tmp/rfe-assess/<PROJECT>/ |
preflight.py | Checks env vars, cache state, and current run status |
setup_run.py | Creates timestamped run directory with resume support (detects incomplete runs via current symlink) |
agent_prompt.md | Full scoring rubric and instructions for assessment agents — use verbatim |
next_batch.py | Pops the next N keys from the queue file; ensures each key is processed exactly once |
wait_wave.py | Blocks until a wave's keys all have .result.md (exit 0) or returns pending (exit 3) — removes completion-tracking from the coordinator's context |
check_progress.py | Reports completed vs total issues for a run directory |
dispatch_context.py | Post-compaction recovery: re-injects the active run's state and loop steps; invoked by the SessionStart compact hook (hooks/hooks.json) |
parse_results.py | Extracts scores from .result.md files into scores.csv; handles format variants |
fetch_single.py | Fetches a single Jira issue via REST API v3 (fallback for when MCP is unavailable), writes to /tmp/rfe-assess/single/ |
prep_single.py | Cleans up stale data/result files for a key in /tmp/rfe-assess/single/ before a single-mode run |
summarize_run.py | Produces summary analysis from scores.csv: pass/fail rates, criteria averages, what-if analysis, near-misses |
Add to your user or project .claude/settings.json:
{
"permissions": {
"allow": [
"Bash(python3 <SKILL_PATH>/scripts/preflight.py:*)",
"Bash(python3 <SKILL_PATH>/scripts/dump_jira.py:*)",
"Bash(python3 <SKILL_PATH>/scripts/setup_run.py:*)",
"Bash(python3 <SKILL_PATH>/scripts/next_batch.py:*)",
"Bash(python3 <SKILL_PATH>/scripts/wait_wave.py:*)",
"Bash(python3 <SKILL_PATH>/scripts/check_progress.py:*)",
"Bash(python3 <SKILL_PATH>/scripts/parse_results.py:*)",
"Bash(python3 <SKILL_PATH>/scripts/summarize_run.py:*)",
"Bash(python3 <SKILL_PATH>/scripts/fetch_single.py:*)",
"Bash(python3 <SKILL_PATH>/scripts/prep_single.py:*)",
"Bash(mkdir:*)",
"Bash(ls:*)",
"mcp__atlassian__getJiraIssue",
"mcp__atlassian__searchJiraIssuesUsingJql"
],
"additionalDirectories": [
"/tmp/rfe-assess",
"<SKILL_PATH>"
]
}
}
<SKILL_PATH> is a placeholder for the absolute path to the skills/assess-rfe/ directory in this plugin. The additionalDirectories entries allow agents to read the scoring rubric and scripts, and read/write cached issues and results in /tmp/rfe-assess/.
npx claudepluginhub opendatahub-io/assess-rfe --plugin assess-rfeWhole-repo audit for over-engineering: finds dead code, unnecessary abstractions, stdlib-replaceable dependencies. Outputs ranked findings and net line/dep savings.