feedback-triage
A triage tool for investigating LLM response failures by tracing individual call chains through verifier and rewriter logs.
Install
mkdir -p .claude/skills/feedback-triage && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/16454" && unzip -o skill.zip -d .claude/skills/feedback-triage && rm skill.zipInstalls to .claude/skills/feedback-triage
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Use when the user mentions a thumbs-down, asks "what went wrong with this nudge/chat/coach/insight", references a specific feedback id, or asks to look at recent feedback. Covers the triage flow (how to walk an LLM call trace), how to localize a bug across the source/verify/rewrite chain, how to cross-check user-reported contradictions against data resyncs, and when to escalate to an eval (hand off to the `llm-evals` skill).Key capabilities
- →List recent feedback items
- →Inspect LLM call traces for specific IDs
- →Localize bugs across source, verifier, and rewriter calls
- →Cross-check user claims against data resyncs
- →Cross-check rendered prompt data against canonical DB data
- →Decide on next steps for bug resolution
How it works
The skill examines LLM call traces, identifies the stage where a failure occurred (source, verifier, or rewriter), and cross-references user claims with data to localize bugs and determine appropriate next steps.
Inputs & outputs
When to use feedback-triage
- →Debug why an AI nudge returned an incorrect insight
- →Review logs of a failed AI interaction
- →Trace the verification pipeline for a specific feedback ID
About this skill
Feedback Triage (zdrowskit)
Analyze an existing thumbs-down or bad LLM output. Once the failing stage is clear and reproducible enough, hand off to llm-evals.
Fast Path
- List feedback:
uv run python main.py llm-log --feedback(or--feedback --json). - Inspect the cited call:
uv run python main.py llm-log --id <llm_call_id>. - Use the trace table as the map. For compact view:
uv run python main.py llm-log --trace <trace_id>. - Identify the delivered stage, then inspect only the relevant prompt, tool result, and final response.
Read The Trace
All related provider calls share trace_id: tool-loop iterations, synthesis retries, verifier, and rewriter.
iteration: 0,1, ...: tool loop / draft calls.iteration: final_synthesis,truncation_retry,empty_retry: recovery or answer synthesis.stage: verify: verifier call.stage: rewrite: bounded rewriter call.
response_text / Final Response is the delivered text. If metadata has postprocessed_response_text: true, inspect metadata.raw_response_text too.
For tool failures, compare the tool request and result inside the same trace. Repeated or near-repeated SQL/results usually means the model failed to synthesize from evidence it already had.
Assign Ownership
For nudge/coach/insights, bugs can live in source draft, verifier, or rewriter:
- Source draft wrong: prompt/context/data assembly issue, or source model quality.
- Verifier missed real issue: verifier under-active.
- Verifier invented issue: verifier over-active / model-quality problem. The call-601 pattern: the draft correctly said HRV was "still declining" (41.6 today vs 44.9 yesterday), the verifier called that an increase, and the rewriter shipped "up slightly from yesterday's 44.9". The user blamed the nudge writer, which had done nothing wrong.
- Rewriter mangled valid correction: rewriter prompt/model issue.
The stage the user names is the surface they saw, not necessarily the stage that broke. Walk the whole trace before seeding an eval against the writer.
Read each stage's Final Response before assigning blame. The delivered text is the rewrite output when a rewrite exists; otherwise it is the source draft.
Check Data First
The user's complaint can be true while the LLM faithfully followed bad or stale prompt data.
- Resync drift: HRV and other Apple Health metrics can change later in the day. A morning nudge may quote HRV 35 ms while the evening reads 44.9 ms for the same date after a later sync — the model faithfully read the snapshot in front of it, and the user sees self-contradiction. Compare historical text in
recent_nudges_textwith currenthealth_data_textbefore calling it a contradiction bug. - Prompt assembly bug: compare rendered prompt data with canonical DB rows via
store.open_db(store.default_db_path())orstore.connect_db(..., migrate=True). When they disagree, the bug is in the assembly path —store.load_snapshots()/llm_health.build_llm_data()— not in the writer or verifier. - Manual data precedence: manual sleep lives in
manual_sleepandsleep_allby night-start date. If manual and imported sleep both exist, prompt context should prefer manual.
If prompt data was wrong, fix the data assembly path and add deterministic coverage there. Usually not an LLM eval.
Decide
- Verifier introduced the bug: model-quality issue. A/B verifier route reasoning via
main.py modelsor Telegram/models(DeepSeekhighengages thinking;mediumleaves it off). Capture asverification_judgereal_regression if reproducible (surface —nudge/insights/coach— set byfixture.kind). - Source draft already had it: prompt/context/model issue. Capture as
chator the relevant source surface if reproducible. - Rewriter mangled a correct correction: rewriter prompt/model issue.
- Data resync caused user confusion: product/prompt issue, not an eval.
- Prompt context was wrong: data assembly fix plus deterministic loader/rendering regression.
Bad Nudge Cleanup
If a delivered nudge is factually wrong and would contaminate future prompts, remove it from daemon state after the root cause is fixed:
- Inspect
~/Documents/zdrowskit/.daemon_state.json. - Remove only the bad entry from
recent_nudges. - Recompute
last_nudge_tsfrom the first remaining nudge, or set it tonull. - Recompute
nudge_count_todayfrom remainingrecent_nudgeswhosetsstarts withnudge_date. - Verify the bad phrase/timestamp no longer appears in state JSON.
Archives under ~/Documents/zdrowskit/Nudges/ are historical records. Do not delete them unless the user explicitly asks.
Eval Handoff
A real regression should reproduce at least roughly 20% under the same config. Below that, capture only if high-impact or structurally likely to recur. Run 5x as the cheap check.
When stage and surface are clear, switch to llm-evals. Supported eval features today: chat (full tool loop, --model-driven) and verification_judge (verifier-only, env-driven; fixture.kind selects nudge / insights / coach). Both share the run_verify.py runner for the verifier path.
Pitfalls
- Multi-model pipelines: nudge uses draft / verify / rewrite routes from
src/config.pyandsrc/model_prefs.py.--modelon eval runner only flows to chat. For verifier evals, change verifier model viaZDROWSKIT_VERIFICATION_MODELand reasoning viamain.py models/ Telegram/models. - Empty-verifier-response false-pass: if verifier hits output cap, failure emits "verifier returned empty" critical issue.
text_absentassertions can trivially pass; add an assertion rejecting that failure mode. - Verifier writes source metadata: source-call metadata already contains verifier verdict and call IDs.
When not to use it
- →When the user wants to capture a reproducible bug as a regression case (hand off to `llm-evals` instead)
- →When the issue is a user-perception bug from data resync, not an LLM eval target
Limitations
- →Not for capturing reproducible bugs as regression cases
- →Does not directly fix bugs, but localizes them
- →Relies on available LLM call traces and metadata
How it compares
This skill provides a structured triage process for LLM failures, systematically analyzing call traces and data discrepancies, which is more efficient and targeted than general debugging approaches.
Compared to similar skills
feedback-triage side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| feedback-triage (this skill) | 0 | 3mo | No flags | Advanced |
| granola-incident-runbook | 1 | 1mo | Review | Intermediate |
| analyzing-logs | 14 | 1mo | Review | Beginner |
| sentry | 10 | 4mo | Caution | Beginner |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
granola-incident-runbook
jeremylongshore
Incident response procedures for Granola meeting capture issues. Use when handling meeting capture failures, system outages, or urgent troubleshooting situations. Trigger with phrases like "granola incident", "granola outage", "granola emergency", "granola not recording", "granola down".
analyzing-logs
jeremylongshore
Analyze application logs to detect performance issues, identify error patterns, and improve stability by extracting key insights.
sentry
openai
Use when the user asks to inspect Sentry issues or events, summarize recent production errors, or pull basic Sentry health data via the Sentry API; perform read-only queries with the bundled script and require `SENTRY_AUTH_TOKEN`.
obsidian-incident-runbook
jeremylongshore
Troubleshoot Obsidian plugin failures with systematic incident response. Use when plugins crash, data is corrupted, or users report critical issues with your Obsidian plugin. Trigger with phrases like "obsidian crash", "obsidian plugin broken", "obsidian incident", "debug obsidian failure", "obsidian emergency".
obsidian-observability
jeremylongshore
Set up comprehensive logging and monitoring for Obsidian plugins. Use when implementing debug logging, tracking plugin performance, or setting up error reporting for your Obsidian plugin. Trigger with phrases like "obsidian logging", "obsidian monitoring", "obsidian debug", "track obsidian plugin".
langsmith-observability
davila7
LLM observability platform for tracing, evaluation, and monitoring. Use when debugging LLM applications, evaluating model outputs against datasets, monitoring production systems, or building systematic testing pipelines for AI applications.