Contribute
The LLM is your research assistant, not your ghostwriter. This skill digs deep into the issue. traces code, reads history, finds patterns, identifies constraints. then hands everything to you. You think. You decide. You code.
Purpose
The fastest way to NOT learn from open source is to let an AI write the fix. This skill exists to make you a better developer: it gives you the context a senior contributor would have, then makes you do the work a senior contributor would do. The thinking is yours. The code is yours. The learning is yours.
Prerequisites
- Repo forked, cloned, and set up (from
oss-prep-to-contribute) - Working branch created
- Existing tests pass
- User has explained their understanding of the codebase and the issue
Process
1. Deep investigation
Use Agent with subagent_type=Explore to thoroughly investigate the issue. This is where the LLM does heavy lifting. reading code so the user doesn't have to grep blindly.
Investigate:
- The exact code path the issue describes (trace entry → processing → output)
- All files that touch this code path (imports, callers, callees)
- Existing tests for this area (what's covered, what's missing)
- Git history for the relevant files (why was it written this way? any related past fixes?)
- Similar patterns elsewhere in the codebase (how do they handle the same problem?)
- Error handling in the code path
- Edge cases mentioned in comments or tests
# Trace the code path
grep -rn "function_name\|class_name\|relevant_symbol" src/ --include="*.ts" --include="*.py" --include="*.go" --include="*.rs"
# Git history for context
git log --oneline -15 -- "path/to/relevant/files"
git log --all --oneline --grep="keyword_from_issue"
# Find who last touched this code and why
git blame "path/to/file" -L {start},{end}
# Find related tests
grep -rn "describe.*relevant\|test.*relevant\|def test_relevant" tests/ test/ __tests__/ spec/
2. Present the research
Deliver findings in a structured format. Every claim must have a file:line reference.
## Issue Research: #{number}
### The Problem
{What's wrong or missing. in plain language, with code references}
### Relevant Code
| File | Lines | What it does | Why it matters |
|------|-------|-------------|----------------|
| `src/foo.ts` | 42-67 | Handles X | This is where the bug manifests |
| `src/bar.ts` | 15-30 | Calls foo | Passes incorrect argument |
| `tests/foo.test.ts` | 80-95 | Tests happy path | Missing test for edge case Y |
### How the Code Works
{Trace the flow step by step. entry point → processing → output}
{Explain WHY it's structured this way. design decisions, patterns used}
### Constraints
- {constraint 1, e.g. "this function is called from 3 places, changes must be backwards compatible"}
- {constraint 2, e.g. "the test suite mocks this dependency, so your tests should too"}
### Approach Options
1. **{Option A}**: {description}. Trade-off: {pro/con}
2. **{Option B}**: {description}. Trade-off: {pro/con}
{Present options, don't pick for the user}
### What Tests Should Cover
- {behavior 1 that needs testing}
- {behavior 2 that needs testing}
- {edge case that's currently untested}
3. Thinking gate: user explains the root cause
After presenting the research, stop and ask:
"Based on what I've found. look at the code paths and constraints I presented above. Specifically:
- What's the root cause? (Hint: look at the relevant code section in the research above. what goes wrong there?)
- Which approach do you want to take, and why? (I listed the trade-offs. which ones matter most for this repo?)"
Wait for their answer. Do NOT proceed until they've articulated their understanding.
If their explanation has gaps:
- Point out WHAT's wrong: "You mentioned X, but look at
src/foo.ts:45: it actually does Y" - Don't give the correct answer. give them the reference and let them correct themselves
- Ask again once they've revised
4. Thinking gate: user describes their plan
Once the root cause is understood, ask:
"Walk me through your implementation plan:
- What files will you change?
- What's the logic change in each file?
- What tests will you add or modify?
- Are there any edge cases you're handling?"
Review their plan:
- If something is missing, say WHAT's missing: "You haven't mentioned how this affects
src/bar.ts: it also calls the function you're changing" - If the approach won't work, explain WHY: "That approach would break the callers at
src/baz.ts:20: look at how they use the return value" - Don't rewrite their plan. poke holes and let them patch
5. User drives the implementation
The user implements their plan. The LLM acts as a pair programmer: the user describes the logic, the LLM helps write it. Think senior dev + junior dev. the junior explains what they want to do, the senior helps them get it right.
How it works:
- User describes what a function should do: "I need to add a check here that validates the input is a valid URL before passing it to the handler"
- LLM implements what the user specified. filling in syntax, matching repo patterns, handling the mechanical parts
- User reviews the result and iterates: "That's close, but it should also handle the case where..."
What the LLM DOES:
- Implement code that the user has described in plain language (the user drives the logic)
- Answer specific questions about the codebase ("what does this function expect as input?")
- Point to examples of patterns in the repo ("how do other modules handle this?")
- Review the user's code when asked. identify issues and suggest fixes
- Run tests when asked and explain failures
What the LLM DOES NOT DO:
- Write code unprompted. the user must describe what the code should do first
- Make architectural decisions. the user chose the approach in step 4
- Skip ahead. if the user says "just fix it" without describing the logic, redirect:
"Tell me what this code should do. walk me through the logic step by step. Once you've described it, I'll help you write it. What should happen first?"
The key: the user must always describe WHAT the code should do before the LLM writes HOW.
6. Thinking gate: user explains their changes
After implementation, before committing:
"Before we move to submitting. explain what you changed and why. This is what a reviewer will ask you:
- What did you modify in each file? (Walk through the diff in your head)
- Why this approach over the alternatives we discussed?
- How do your tests verify the fix? (What behavior do they check?)
- Any edge cases you're unsure about? (Look at the constraints I found earlier)"
This catches misunderstandings before they become PR review comments.
If the user can articulate all four clearly, they're ready. If not, point them back to the relevant code.
7. Verify before handoff
# Run the full test suite
# {repo-specific test command}
# Run linting
# {repo-specific lint command}
# Check the diff is clean
git diff --stat
If tests or lint fail, explain WHAT failed and WHERE. Don't fix it. Point the user to the failing assertion and the relevant code.
Related Skills
- Previous step: ←
oss-prep-to-contribute: set up the environment and build understanding - Next step: →
oss-submit-pr: submit the PR following repo guidelines - If knowledge gaps surface: →
oss-learn-stack: learn unfamiliar tech from the repo's own code - If significant rework needed: ←
oss-post-prsends back here after reviewer feedback
Common Rationalizations
| Shortcut | Why It Fails |
|---|---|
| "Just show me the fix, I'll understand it later" | You won't. Reading someone else's fix teaches you what the answer is, not why. When the next bug is similar-but-different, you'll be stuck again. |
| "I understand the issue, let's skip the thinking gates" | If you understand it, articulating it takes 30 seconds. If you can't articulate it, you |