一键导入
triage-failures
Use when user wants to Analyze OCR failure corpus to find systematic misreads, top error patterns, and whether unlisted items need rules added
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when user wants to Analyze OCR failure corpus to find systematic misreads, top error patterns, and whether unlisted items need rules added
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when user wants to Run the Arc Raiders AutoScrapper validation stack after edits. Use for linting, typing, tests, workflow checks, and broader repo validation.
Use when user wants to Update Metaforge snapshots and bundled default rules
Use when user wants to Validate OCR changes against failure corpus before shipping
Add a new OCR regression fixture from an ocr_debug image. Use when a scan misidentified an item and you want to lock in the correct result as a test case.
Use when user wants to Run full validation, push branch, and open a PR with appropriate context notes
Workflow for safely adding, removing, or renaming persisted config fields in config.py. Use whenever editing dataclass fields in src/autoscrapper/config.py. Covers incrementing CONFIG_VERSION, writing a migration function, and validating the round-trip.
| name | triage-failures |
| description | Use when user wants to Analyze OCR failure corpus to find systematic misreads, top error patterns, and whether unlisted items need rules added |
| disable-model-invocation | true |
Analyze the OCR failure corpus to surface systematic misread patterns:
uv run python - <<'EOF'
import orjson, collections
from pathlib import Path
REPO = Path(".")
files = {
"captured": REPO / "artifacts/ocr/skip_unlisted/samples.jsonl",
"fixed": REPO / "artifacts/ocr/failure_corpus.jsonl",
}
for label, path in files.items():
if not path.exists():
print(f"[{label}] not found: {path}")
continue
samples = [orjson.loads(l) for l in path.read_text().splitlines() if l.strip()]
print(f"\n=== {label} ({len(samples)} samples) ===")
if not samples:
# Top raw→chosen mismatches
mismatches = [(s.get("raw_text",""), s.get("chosen_name","")) for s in samples if s.get("raw_text") != s.get("chosen_name")]
counter = collections.Counter(mismatches).most_common(10)
print("Top raw→chosen mismatches:")
for (raw, chosen), count in counter:
print(f" {count:3d}x {raw!r:40s} → {chosen!r}")
# Items with no match (matched_name is null)
no_match = [s.get("chosen_name","") for s in samples if not s.get("matched_name")]
if no_match:
top_no_match = collections.Counter(no_match).most_common(10)
print("Items with no rule match (consider adding rules):")
for name, count in top_no_match:
print(f" {count:3d}x {name!r}")
# Source breakdown
sources = collections.Counter(s.get("source","?") for s in samples)
print(f"Source: {dict(sources)}")
EOF
Interpreting the output:
raw_text maps to wrong chosen_name: OCR preprocessing issue - check binarization or upscalematched_name is null repeatedly: Item has no rule - use /add-rule skill/dry-run to comparescore_cutoff in item_actions.pyAfter identifying patterns, run /corpus-replay to validate any threshold or preprocessing changes against the fixed corpus.