Borrowing it
Nothing to install: this file belongs to forever-healthy/AI4L. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.
curl -O https://raw.githubusercontent.com/forever-healthy/AI4L/main/.claude/agents/er-combiner.mdgit clone --depth 1 https://github.com/forever-healthy/AI4LWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/agents/forever-healthy/ai4l/er-combiner)<a href="https://agentmods.dev/agents/forever-healthy/ai4l/er-combiner"><img src="https://agentmods.dev/badge/agents/forever-healthy/ai4l/er-combiner.svg" alt="Measured on agentmods" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00022 | $0.01180 |
| Opus 5 | $0.00011 | $0.00590 |
| Sonnet 5 | $0.00004 | $0.00236 |
| Haiku 4.5 | $0.00002 | $0.00118 |
Grade A, and why
er-combiner scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 3d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
What it actually says
AI4L - Bash Agent to Combine all QA files of an ER into a single file
-
Set [er_filename] to $ARGUMENTS
-
READ SCOPE — you may read ONLY the QA files belonging to [er_filename], via the script below. Never read another evidence review or another review's QA files, and never glob or search for them beyond the script's own pattern.
-
Report
COMBINER: Work on QA files for [er_filename]
Run this bash script (substituting [er_filename], [creation_dir], and [trash_dir] for their actual values):
#!/usr/bin/env bash
set -euo pipefail
ER_FILE="[er_filename]"
CREATION_DIR="[creation_dir]"
TRASH_DIR="[trash_dir]"
# Derive base name by stripping the .md extension (keeps the _ER suffix)
base="${ER_FILE%.md}"
# Find all timestamped QA files, sorted descending by name (date suffix is lexicographically sortable)
mapfile -t qa_files < <(ls -r "${CREATION_DIR%/}/${base}_QA_"*.md 2>/dev/null || true)
count=${#qa_files[@]}
if [[ $count -eq 0 ]]; then
echo "Error: no timestamped QA files found for $ER_FILE"
exit 1
fi
echo "Found $count QA file(s):"
for f in "${qa_files[@]}"; do echo " $f"; done
# Sum audit_duration (HH:MM) across all QA files
total_min=0
for f in "${qa_files[@]}"; do
d=$(awk '/^audit_duration:/{sub(/^audit_duration:[[:space:]]*/,""); gsub(/[[:space:]"]/,""); print; exit}' "$f")
if [[ "$d" =~ ^([0-9]+):([0-9]+)$ ]]; then
total_min=$(( total_min + 10#${BASH_REMATCH[1]} * 60 + 10#${BASH_REMATCH[2]} ))
fi
done
audit_duration=$(printf '%02d:%02d' $((total_min / 60)) $((total_min % 60)))
# Latest is first after reverse sort
latest="${qa_files[0]}"
# New filename: base already ends in _ER, so this yields ..._ER_QA.md (no date suffix)
new_filename="${base}_QA.md"
new_filepath="${CREATION_DIR%/}/${new_filename}"
# Copy the latest QA file verbatim as the base
cp "$latest" "$new_filepath"
echo "Base: $latest -> $new_filepath"
# Update frontmatter: set audit_filename, audit_iterations, audit_duration
awk -v fn="$new_filename" -v itr="$count" -v dur="$audit_duration" '
BEGIN { in_fm=0; done_fm=0; found_fn=0; found_itr=0; found_dur=0 }
/^---/ && !done_fm {
if (!in_fm) { in_fm=1; print; next }
else {
if (!found_fn) print "audit_filename: " fn
if (!found_itr) print "audit_iterations: " itr
if (!found_dur) print "audit_duration: \"" dur "\""
done_fm=1; print; next
}
}
in_fm && /^audit_filename:/ { print "audit_filename: " fn; found_fn=1; next }
in_fm && /^audit_iterations:/ { print "audit_iterations: " itr; found_itr=1; next }
in_fm && /^audit_duration:/ { print "audit_duration: \"" dur "\""; found_dur=1; next }
{ print }
' "$new_filepath" > "${new_filepath}.tmp" && mv "${new_filepath}.tmp" "$new_filepath"
# Extract pass_rate from summary table and normalize to 2 decimal places
pass_rate=$(awk '/\*\*Pass Rate\*\*/{
if (match($0, /[0-9]+\.?[0-9]*%/)) {
raw = substr($0, RSTART, RLENGTH - 1)
printf "%.2f%%", raw + 0
exit
}
}' "$new_filepath")
# Append Issues+Fixes sections from older files in descending order (skip index 0 = latest)
for ((i=1; i<count; i++)); do
qa_file="${qa_files[$i]}"
echo "Appending from: $qa_file"
# Extract from the first ## Issues line to end of file
awk '/^## Issues /{found=1} found{print}' "$qa_file" >> "$new_filepath"
echo "" >> "$new_filepath"
done
# Move all timestamped QA files to trash
mkdir -p "$TRASH_DIR"
for qa_file in "${qa_files[@]}"; do
mv "$qa_file" "$TRASH_DIR/"
echo "Trashed: $qa_file"
done
echo ""
echo "QA file: $new_filename"
echo "audit_iterations: $count"
echo "audit_duration: $audit_duration"
echo "pass_rate: $pass_rate"
-
Run the script
-
Return the last 4 lines of output as the result
-
Report
COMBINER: Done with [topic]
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 3d ago First seen · 116 lines · 22 tokens per session scan A 1b1eb380e445
er-combiner is an agent published in the GitHub repository forever-healthy/AI4L (38 stars, last pushed 11d ago), licensed MIT. It adds 22 tokens to every session and 1,180 once invoked, about $0.0001 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-04.
Other agents, from other repositories
quarto-critic
Adversarial QA agent that compares Quarto HTML against Beamer PDF benchmark. Produces harsh, actionable criticism. Does NOT edit files — read-only analysis only.
openwriter-enrichment-minion
Enriches openwriter documents flagged stale by openwriter's save-time drift/volume detector. Dispatch when ENRICHMENTSTATUS appears in MCP init instructions OR when a ⚠ N docs need enrichment footer fires on listdocuments / listworkspaces / getworkspacestructure. Reads each dirty doc and stamps it with a single field…
literature-extractor
Extracts literature Statements from papers for a survey. Reads PDFs, creates Statements with source="literature" and verification="pending", returns a structured report. Never registers theme tags, never creates Warrants or Claims.
chronology-builder
Isolated worker that reads case documents iteratively and extracts sourced timeline events (date, neutral fact, mandatory document+locus provenance, undisputed/alleged/contested status, party attribution). Deduplicates and cross-references across documents and languages. Emits events.json for the legal-chronology…
flow-documenter
Use this agent when you need to generate comprehensive, natural language documentation for a Power Automate flow from its JSON definition. This agent should be invoked when:\n\n- A user provides a flow.json file and requests documentation\n- A new flow has been created and needs to be documented\n- An existing flow…
timps_log_interpreter
Read crash logs and system logs, extract stack traces, and explain each crash in plain English. Classifies as app bug / OS bug / hardware / user error. Pass a log file path to analyse a specific log. Use the timpsloginterpreter MCP tool to perform this task. Do not answer directly — delegate to this sub-agent.