skills/ds-fix/SKILL.md
This skill should be used when the user asks to 'fix analysis', 'wrong results', 'notebook error', 'reviewer feedback', 'data changed', 'debug notebook', or needs mid-analysis course-correction for wrong results, notebook errors, or data changes.
npx skillsauth add edwinhu/workflows ds-fixInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Announce: "Using ds-fix for mid-analysis course correction."
Before starting, check for an existing handoff:
.planning/HANDOFF.md exists/ds (entry) → brainstorm → plan → implement → review → verify
↑
/ds-fix (midpoint) ─────────────────┘
This is the re-entry point. Jump back into a DS workflow that needs fixing.
<EXTREMELY-IMPORTANT> ## The Iron Law of DS EditingDIAGNOSE BEFORE FIXING. This is not negotiable.
Before changing ANY analysis code, you MUST:
If you're about to change code without diagnosing first, STOP. </EXTREMELY-IMPORTANT>
Read workflow state, shared enforcement, AND shared check definitions:
As the midpoint, auto-load ALL constraints matching applies-to: ds-fix (midpoint can route to any phase):
!uv run python3 ${CLAUDE_SKILL_DIR}/../../scripts/load-constraints.py ds-fix
You MUST have these constraints loaded before proceeding. No claiming you "remember" them.
Read(".planning/SPEC.md")
Read(".planning/PLAN.md")
Read(".planning/LEARNINGS.md")
Read ${CLAUDE_SKILL_DIR}/../../skills/ds-implement/references/ds-checks.md and follow its instructions.
The shared checks file contains data quality check definitions (DQ1-DQ6, M1, R1) used by both ds-review and ds-fix. Loading it here ensures the midpoint runs identical checks to the entry point's review phase. Without it, checks drift apart and the midpoint misses issues review would catch.
If no workflow state exists, suggest starting with /ds instead.
After loading PLAN.md, check if Implementation Language is SAS or Mixed. If so, reload SAS enforcement before any fix:
Read ${CLAUDE_SKILL_DIR}/../../skills/wrds/references/sas-etl.md and follow its instructions.
SAS projects have unique failure modes (hash merge memory, WHERE function wrapping, SGE array misconfiguration). The SAS enforcement must be loaded BEFORE diagnosing — otherwise you will misdiagnose SAS-specific issues as generic bugs.
Before starting diagnosis, check context availability:
| Level | Remaining Context | Action | |-------|------------------|--------| | Normal | >35% | Proceed with diagnosis and fix | | Warning | 25-35% | Complete current fix, then invoke ds-handoff | | Critical | ≤25% | Invoke ds-handoff immediately — no new fixes |
At Warning level: After current fix completes, invoke:
Read ${CLAUDE_SKILL_DIR}/../../skills/ds-handoff/SKILL.md and follow its instructions.
Why: A multi-step fix pipeline with 20% context remaining produces degraded output. Better to handoff cleanly and resume fresh.
Identify the issue category:
| Category | Symptoms | Route To | |----------|----------|----------| | Runtime Error | Traceback, cell failure, import error | Debug Protocol | | Wrong Results | Numbers don't match expectations, sanity checks fail | Re-analysis Protocol | | Unclear Root Cause | 3+ plausible explanations, mysterious data quality issues | Competing Hypothesis Investigation | | Reviewer Feedback | Specific methodology concerns, requested changes | Revision Protocol | | Data Change | New data available, source updated, schema changed | Re-profiling Protocol | | Scope Change | New questions, expanded requirements | Spec Update → re-plan |
Ask user if ambiguous:
AskUserQuestion(questions=[
{
"question": "What needs fixing in your analysis?",
"header": "Issue type",
"options": [
{"label": "Runtime error", "description": "Code fails, traceback, import error"},
{"label": "Wrong results", "description": "Numbers don't look right, sanity checks fail"},
{"label": "Unclear root cause", "description": "Multiple plausible explanations, mysterious data quality"},
{"label": "Reviewer feedback", "description": "Specific changes requested by reviewer"},
{"label": "Data/scope change", "description": "New data, updated requirements, new questions"}
],
"multiSelect": false
}
])
┌───────────────────────┐
│ Load Context (Step 1) │
│ SPEC + PLAN + LEARN │
└───────────┬───────────┘
▼
┌───────────────────────┐
│ Identify Symptoms │
│ (Step 2) │
└───────────┬───────────┘
▼
┌──────┴──────┐
│ Traceback? │─── YES ──→ Debug Protocol
└──────┬──────┘ (Runtime Error)
│ NO
▼
┌──────────────┐
│ Numbers wrong │─── YES ──→ Re-analysis Protocol
│ or unexpected?│ (Trace backwards)
└──────┬───────┘
│ NO
▼
┌──────────────┐
│ 3+ plausible │─── YES ──→ Competing Hypothesis
│ explanations?│ (Parallel investigation)
└──────┬───────┘
│ NO
▼
┌──────────────┐
│ Reviewer │─── YES ──→ Revision Protocol
│ feedback? │ (Fix per feedback)
└──────┬───────┘
│ NO
▼
┌──────────────┐
│ Data or scope │─── YES ──→ Re-profiling / Spec Update
│ changed? │
└──────────────┘
This flowchart IS the diagnostic spec. If the category table and flowchart disagree, the flowchart wins.
For notebook-specific errors, load notebook-debug patterns:
Read ${CLAUDE_SKILL_DIR}/../../skills/notebook-debug/SKILL.md and follow its instructions.
The bug is at the FIRST step where output diverges from expected. Find that step. </EXTREMELY-IMPORTANT>
Read ${CLAUDE_SKILL_DIR}/../../skills/ds-review/SKILL.md and follow its instructions.
If the question itself changed:
When 3+ plausible explanations exist, sequential investigation failed, or contradictory evidence is found, use the competing hypothesis protocol.
MANDATORY: Before proceeding, load the protocol:
Read("${CLAUDE_SKILL_DIR}/references/competing-hypothesis.md")
Key steps:
After fixing, apply output-first verification:
Checkpoint type: human-verify (fix output is machine-verifiable)
Before claiming any fix is done, execute this gate:
1. IDENTIFY → What specific behavior was broken? (not vague — exact symptom)
2. RUN → Execute the fixed code with output-first verification
3. READ → Read the output: does it match SPEC.md success criteria?
4. VERIFY → Re-run downstream steps — no cascading failures introduced
5. CLAIM → Only declare "fix complete" if ALL gates pass
Skipping this gate means your fix is unverified. An unverified fix is not a fix — it's a guess.
Step 2's diagnosis IS the work-list — re-asking permission per item is stalling, and LEARNINGS.md is the summary (repeating it in chat wastes context). A verified fix means start the next one.
The fix loop runs until every issue in Step 2's diagnosis is resolved OR a STOP escalation (R4 / rethink) is required. Your pause is procrastination disguised as courtesy. </EXTREMELY-IMPORTANT>
ALLOWED: Read the agent's returned report. Check LEARNINGS.md. Confirm file existence with ls.
FORBIDDEN: Read project source code, run analysis code, inspect data files, Grep/Glob project files.
If the fix looks incomplete, re-dispatch a Task agent. Do NOT investigate yourself. </EXTREMELY-IMPORTANT>
If user sends an off-topic message during ds-fix, follow the Topic Change Protocol (constraints/ds-topic-change-protocol.md):
.planning/SPEC.md, .planning/PLAN.md, .planning/LEARNINGS.md.Main chat orchestrates. Task agents do the fixing:
Task(subagent_type="general-purpose", prompt="""
Fix [SPECIFIC ISSUE] in the analysis.
Context:
- Read .planning/LEARNINGS.md for prior steps
- Read .planning/PLAN.md for task details
- Read .planning/SPEC.md for objectives
Fix Protocol:
1. Trace to root cause (do NOT guess)
2. Fix with output-first verification
3. Print state BEFORE and AFTER fix
4. Re-run downstream steps
5. Update LEARNINGS.md
Report: what was wrong, what was fixed, verification output.
""")
| Scenario | Action | |----------|--------| | You wrote fix code (> 3 lines) directly in main chat | DELETE immediately. Re-dispatch a Task agent with the diagnosis. | | You partially applied a fix in main chat before catching yourself | DELETE the changes. Re-dispatch with full context (don't leave a half-fix). | | You ran a "quick" patch cell in the orchestrator notebook | DELETE the cell + output. Re-do via Task agent. | | "It's a one-line fix, delegating is overkill" | STOP — a one-line fix is one line for the agent too. Delete and delegate. |
Helpfulness Check: A fix that "works" but was written in the wrong place skipped verification and review. Working code in the wrong place is anti-helpful — delete it and re-dispatch. </EXTREMELY-IMPORTANT>
If the fix reveals the analysis approach is fundamentally wrong:
/ds for re-planningDon't try to salvage a broken approach with patches. A fresh plan costs less than cascading fixes.
development
Build the meeting-level proxy-voting × ownership panel on the WRDS SGE grid — ISS N-PX fund votes reduced to (item × block) direction cells, joined to institutional and mutual-fund ownership. Use when working with risk.voteanalysis_npx, N-PX fund-level votes, ISS→CRSP fund linking, index/passive/active voting blocks, or a proxy-voting panel that needs ownership attached.
development
Use when "CRSP CIZ", "CRSP v2", "CRSP flat file format 2.0", "crsp.dsf_v2 / msf_v2", "StkDlySecurityData", "StkMthSecurityData", "StkSecurityInfoHist", "stocknames_v2", "DlyRet / MthRet / DlyPrc / MthPrc", "SHRCD or EXCHCD equivalent in new CRSP", "SIZ to CIZ migration", "CRSP data after 2024", "CRSP delisting returns", "CRSP cumulative adjustment factors", "CRSP index INDNO / INDFAM", or any CRSP stock/index query where the legacy SIZ column names no longer exist.
development
Use when linking or deduping datasets by entity name rather than a shared key — 'fuzzy match', 'fuzzy name matching', 'entity resolution', 'record linkage', 'match company/person names', 'dedupe entity names', 'name-based join', 'bridge identifiers' (CIK ↔ permno ↔ gvkey ↔ wficn ↔ EIN ↔ personid), or any use of char n-gram TF-IDF, cosine similarity on names, `sparse_dot_topn`, or RapidFuzz at scale.
development
Use when building a publication-quality table in Python — 'regression table', 'results table', 'summary statistics table', 'etable', 'coefplot', 'great_tables', 'GT', 'gt table', 'format a table for the paper', 'export table to LaTeX/HTML', significance stars, spanners, or column formatting for a table headed into a paper, slide deck, or notebook.