SKILL DETAIL
oss-contributor-onboarding
samber/developer-relations-skills/oss-contributor-onboarding
Designs and verifies the path a stranger walks to their first merged contribution on an open-source project - the CONTRIBUTING file, the good-first-issue queue, a clone-to-passing-tests command that works cold, and the first-pull-request review and recognition loop, scored against a blocking-plus-weighted rubric. Use whenever someone says "nobody contributes to my project", "write a CONTRIBUTING.md", "our good first issues get no takers", "first-time contributors disappear", "contributor onboarding", "first pull request experience", or "how do we get more open-source contributors" - even if they only complain about a lonely repo. Not triage-system design - use samber/developer-relations-skills@oss-issue-triage. Not governance or CLA choice.
Installation
npx skills add https://github.com/samber/developer-relations-skills --skill oss-contributor-onboarding
技能文件
SKILL.md
最近同步 · 2026年10月23日
evals/evals.json›
{
"skill_name": "oss-contributor-onboarding",
"evals": [
{
"id": 1,
"prompt": "I maintain Quillrail, an open-source Go library for streaming CSV transforms. 6,200 stars, 41 forks, and in 18 months exactly three pull requests from people who aren't me - two typo fixes and one I closed. I've rewritten the CONTRIBUTING.md twice this year and slapped a 'good first issue' label on eleven old bugs. Nothing changed. What copy should I use in the contributing guide so people actually send code?",
"expected_output": "A refusal to start from file wording, a baseline measurement, and a scored audit of the current path shown to the maintainer before any change is proposed.",
"files": [],
"expectations": [
"Declines to start with contributing-guide wording, and says this symptom usually points at the environment step or the review-and-response step rather than the wording of any file",
"Scores the current path against the scorecard and shows the maintainer the result before proposing changes",
"Names the four blocking checks: contribution is invited, the documented setup runs cold, there is work available, submissions get answered",
"States there are eight scored checks worth 0-2 points each, 16 points total",
"States the pass threshold as all four blocking checks passing plus at least 12 of 16 scored points",
"States that the 12-of-16 mark is this skill's own baseline rather than a published standard",
"Requires a cold run from a clean machine before the setup check can be marked as passing",
"Flags the eleven relabelled old bugs as a likely failure: small for someone who knows the codebase is not small for a stranger",
"Asks to read the last ten pull requests from non-maintainers, oldest comment first, noting where each stalled and what the first maintainer reply said",
"Requires evidence attached to every finding - a file path and line, a command output, or a counted number with its date",
"Names which of the five published newcomer-barrier categories (social interaction, prior knowledge, finding a way to start, documentation, technical hurdles) each finding falls into",
"Does not draft or rewrite CONTRIBUTING prose in this response"
]
},
{
"id": 2,
"prompt": "Please write me a CONTRIBUTING.md for Portmint, a Python CLI that diffs Postgres schemas. It's just me, nights and weekends, maybe 3 hours a week. There's already a CONTRIBUTING.md in the repo root and an older one at docs/contributing.md that I'd forgotten about. Setup needs a running Postgres 16 and `uv sync`; I honestly haven't tried it on a fresh machine since 2024. We use a CLA my old employer set up - the signing bot comments on the PR after you open it. Make it thorough, and link out to our wiki for the build steps since they're long.",
"expected_output": "A short CONTRIBUTING file drafted section by section, with the duplicate resolved, the legal gate moved earlier, the wiki link inlined, and setup commands withheld until a cold run proves them.",
"files": [],
"expectations": [
"Names the two CONTRIBUTING copies as a defect and keeps exactly one",
"States the display precedence when copies exist: .github/ first, then the repository root, then docs/",
"Refuses to publish setup commands that have not been run, and requires a cold run from a clean machine - or the maintainer pasting the full output including failures - before the setup section is written",
"Moves the CLA disclosure into the file before the reader writes code, instead of leaving it to the signing bot after the pull request is opened",
"Routes the CLA-versus-DCO choice itself to samber/developer-relations-skills@oss-license-strategy and keeps only its placement in scope",
"Refuses to leave the mandatory build steps behind the off-repo wiki link, and puts them in the file itself",
"Writes the literal commands out rather than only a wrapper target such as `make setup`",
"States branch naming and commit-message conventions literally and near the top of the file",
"Explains that an unstated convention is overwritten by a contributing agent's own generic template, not merely left undiscovered",
"Publishes a response target sized to the stated 3 hours per week rather than a 48-hour promise, on the ground that an honest target met beats a fast one missed",
"Sizes the file at roughly 150-300 words plus the setup block instead of the thorough document requested",
"Names non-code contributions - documentation, tests, triage, translation, examples - in the scope section",
"Links CODE_OF_CONDUCT, SECURITY, SUPPORT and GOVERNANCE rather than absorbing their content",
"Drafts section by section and gets the maintainer's agreement on each section before moving to the next"
]
},
{
"id": 3,
"prompt": "Our repo Fernbank, an Elixir job-queue library, has 19 open issues labelled `good first issue`. Nobody has touched any of them in seven months. Two are claimed - one by a person who commented in January and hasn't replied since. The rest are one-liners like 'Add retry backoff config' or 'Improve docs for the supervisor'. A friend says the fix is to label more of them and add `help wanted` too. Three maintainers, weekly releases. What do we do with the queue?",
"expected_output": "A rewritten queue with complete issue bodies, a claiming convention with an expiry applied to the stale claim, a standing unclaimed floor, and non-code entry points reserved.",
"files": [],
"expectations": [
"States that a beginner label is a promise of mentoring, not a difficulty rating",
"Distinguishes `good first issue` (members have committed to extra assistance) from `help wanted` (the broader 'we would take a patch'), citing the Kubernetes convention",
"Notes the forge surfaces the `good first issue` label algorithmically and publishes no criteria for it, so the label pulls in strangers from outside the project",
"Rewrites each candidate issue against the seven parts: observed behaviour, expected behaviour, the file and its test, the skills or APIs required, a suggested approach or an explicit 'design not settled', the exact verification command, and a named mentor",
"Adds a technical-domain or skills label, citing the 74-participant study finding newcomers picked issues labelled by the technical domain required over issues labelled by architecture area",
"Sizes each issue at roughly one evening for someone who has never seen the codebase, setup included",
"Identifies the one-evening sizing as this skill's own default rather than a published standard",
"Rejects typo-sized or one-word issues on the ground that they teach nothing and produce a contributor who never returns",
"Publishes a claiming convention and a stale-claim expiry, and applies the expiry to the January claim",
"States that a queue which looks full but is entirely claimed by absent people is worse than an empty one",
"Sets a standing floor of at least three valid unclaimed beginner issues and names it as a self-set default",
"Reserves non-code entry points explicitly - documentation, tests, triage, translation, examples",
"Tells the maintainers to stop fixing the easy bugs themselves, framing each one as a recruiting opportunity spent",
"Declines 'label more issues' as the fix"
]
},
{
"id": 4,
"prompt": "Solo maintainer of Tidewheel, a Rust WASM bundler. I want to sign us up for Hacktoberfest in October and apply as a Google Summer of Code org next year - I read that 80% of Outreachy interns keep contributing, so mentorship looks like the highest-leverage thing I can do. I can give maybe 4 hours a week total, review included. Our setup currently fails on Windows and the last outside pull request waited 3 weeks for a reply. Which program do I start with?",
"expected_output": "Both programs held until the environment and review steps hold, the volume-reward option deleted outright, the imported retention figure corrected, and the explicit orderings given with the hours-per-week constraint applied.",
"files": [],
"expectations": [
"Refuses to rank any accelerator before the environment fix and the review loop hold, stating that on a broken path every one of them scores zero",
"Identifies the Windows setup failure and the 3-week first reply as the work that comes first",
"Deletes the reward-with-no-quality-gate option rather than ranking it last, and says explicitly that it was deleted",
"Cites the 2020 Hacktoberfest spam wave and the response to it: opt-in repositories, a longer grace period, repeat spammers banned, and the T-shirt dropped entirely",
"Corrects the 80% figure as a self-reported 2019 alum survey with a 37% response rate",
"Cites the Mozilla analysis (Labuschagne & Holmes, MSR 2015) finding contributors who started on a good-first-bug or mentored bug were less likely to become long-term contributors",
"States the two most-cited studies disagree and neither used a matched control group, so program-driven retention is unproven in the general case",
"Rules out the structured program because 4 hours per week is under a day and cannot clear a mentor's weekly commitment for a full season",
"Notes the absence of a second reviewer as a further reason to hold the structured program",
"Gives the efficiency ordering: bot > structured program > onboarding event",
"Gives the value ordering: structured program > bot > onboarding event",
"States that a bot may absorb mechanical work but never the first reply, the decline, or the stall check-in",
"Names the compliance obligations each carries - a third party's participation agreement, mentor commitments, stipend administration and a code of conduct for a season; a code of conduct and a venue for an event; neither for a bot",
"Recommends measuring this project's own funnel - time to first response, second-contribution rate - over importing another program's self-reported outcome"
]
},
{
"id": 5,
"prompt": "Someone called @nreddy opened their first pull request on Harborlight, our TypeScript feature-flag SDK, four days ago. It's 340 lines, adds a Redis backend we've never wanted, has a failing lint check, two more failing checks that need our AWS secrets, and the variable names don't match our style. I've been heads-down on a release. What do I write back? And give me something the other two maintainers can follow so this stops happening.",
"expected_output": "A same-day acknowledgement separate from the review, a scope answer in the first comment, a kind fast decline, and a written review-loop playbook for the maintainer team.",
"files": [],
"expectations": [
"Separates acknowledgement from review - a same-day 'I have seen this, full review by <date>' on a different clock from the review itself",
"Names silence, not slowness, as the expensive failure",
"Answers scope in the first comment, saying the Redis backend is out of scope now rather than after review rounds",
"Declines fast and kindly: thanks them, names the scope rule, links where it was published, offers an alternative issue, closes",
"Tells the contributor which failing check they can fix locally and which ones need repository secrets and therefore cannot run on a fork",
"Keeps naming and formatting out of human review comments where the formatter can fix them",
"Gives the fixed review order: scope, then correctness and tests, then design with the reasoning attached, then only the style the formatter missed",
"Labels every review comment as blocking or optional",
"Treats the absence of a published out-of-scope rule as a finding to fix in the CONTRIBUTING file",
"Produces a short written playbook of the review-loop items for the other two maintainers to share",
"Mirrors the published response target into the CONTRIBUTING file so contributors and maintainers read the same number",
"Says a stated target that is honest and met beats a faster one that is missed",
"Prescribes reviewing against the written scope rule and the fixed order rather than against an impression of the person, naming it as the cheapest available control on reviewer bias"
]
},
{
"id": 6,
"prompt": "Beaconlane is a Python/Postgres analytics server, 6 maintainers, corporate-backed. Contributors keep hitting 'psycopg2 build failed' and 'which Python version?'. Our CI already runs everything in Docker. Someone on the team wants to buy GitHub Codespaces seats for contributors - they showed me a page saying prebuilds cut startup from 3-5 minutes to 10-30 seconds and onboarding from one to two weeks down to near-instant. Budget's approved. Do we buy it?",
"expected_output": "A tier decision that promotes the container definition for this stack, adopts the portable format before any vendor, labels the quoted figures as vendor marketing, and closes the CI-parity and fork-secrets gaps.",
"files": [],
"expectations": [
"Names the three reproducibility tiers: bootstrap command, pinned toolchain, container definition",
"Gives the default efficiency ordering: bootstrap command > pinned toolchain > container definition",
"Gives the value ordering: container definition > pinned toolchain > bootstrap command",
"Promotes the container definition for this project because the stack needs a database and a painful toolchain, and because the team already pays that tier's cost in CI",
"Separates adopting the `.devcontainer/` format from choosing a hosted vendor, and adopts the portable format first",
"Labels the 3-5 minutes to 10-30 seconds and the one-to-two-weeks-to-near-instant claims as vendor-reported marketing figures with no peer-reviewed measurement behind them",
"Raises who pays for compute, including that storage bills while a workspace is stopped and that free personal allotments are small",
"Raises portability before hosting, citing Gitpod dropping its self-hosted option in 2024 as the cautionary case",
"Raises drift: a cloud environment the maintainers do not use themselves bit-rots, and local setup stays a first-class path",
"Requires every gate CI enforces to be runnable locally with one documented command",
"Splits the pipeline into a credential-free lane that always runs on fork pull requests and a privileged lane a maintainer triggers",
"Says in the CONTRIBUTING file who approves a held fork run and how fast",
"Turns on maintainer edits to contributor branches and states in the file that this is done",
"Re-runs the cold run from clean after each fix, until nothing new is discovered"
]
},
{
"id": 7,
"prompt": "Here's what we publish for Slatecar, our C++ geospatial indexer. The README says: clone, then `cmake -B build`, `cmake --build build`, `ctest`. The CONTRIBUTING file says run `./tools/dev-setup.sh` first. You don't have the repo and you can't run anything in this conversation. Tell me whether our setup works for a newcomer, and score us on it.",
"expected_output": "A plain statement that the setup check cannot be scored by inspection, plus a cold-run protocol handed to the maintainer with the exact outputs and logs to bring back.",
"files": [],
"expectations": [
"Refuses to mark the setup blocking check as passed by inspection",
"Says plainly that it cannot execute commands in this environment",
"Asks the maintainer to run the sequence and paste the full output, including the failures",
"Specifies a clean start: a fresh container, a new user account, or a machine that has never built this project, with no warm caches, global config, or forgotten credentials",
"Restricts the cold-run reader to the README and the CONTRIBUTING file only, with no repository knowledge already held",
"Asks for wall-clock time to the first passing test run",
"Asks for every undocumented requirement to be logged: system package, environment variable, running service, credential, minimum resource, platform assumption",
"Requires the whole sequence to be re-run from clean after the documentation is fixed, repeated until nothing new is discovered",
"Requests a friction log with a timestamped entry per moment of confusion, each carrying a traffic-light severity, what was expected, what happened, and what had to be known that was not written down",
"Instructs the runner not to fix anything mid-run, because fixing hides the size of the problem",
"Specifies a second, task-path cold run: whether a stranger can pick an issue, understand what is asked, and locate the file to change in under 15 minutes without asking a question",
"Flags the conflict between the README's build sequence and the CONTRIBUTING file's `./tools/dev-setup.sh` as an ordering a stranger must currently guess"
]
},
{
"id": 8,
"prompt": "We ran the numbers on Crestmoor, our Java observability agent. CONTRIBUTING.md is in .github/ and says we take code and docs. A cold run reached passing tests in 22 minutes with one undocumented step - you need JDK 21 exactly, but we write 17+. We have two unclaimed beginner issues, both with a file path and a test command but no mentor named. Median first response to outside issues over 90 days is 9 days; the README publishes '48 hours'. Local commands match CI, fork CI is green. No scope section anywhere. The CLA is mentioned only in the pull request template. We credit contributors in release notes but never point them at a next issue. Score it and tell me whether we can ship the new contributing guide this week.",
"expected_output": "A scored audit in the report format with three blocking failures, a refusal to ship while blocking checks fail, and a fix order ranked by damage removed per hour.",
"files": [],
"expectations": [
"Marks the setup blocking check as failed because the cold run required an undocumented step - exactly JDK 21 against a documented 17+",
"Marks the work-available blocking check as failed because fewer than three unclaimed valid beginner issues exist",
"Marks the submissions-answered blocking check as failed because the 9-day median sits outside the published 48-hour target",
"States that this check cannot be fixed by publishing a slower target and then meeting it, and records the honest target as a finding rather than a pass in disguise",
"Scores the out-of-scope-stated check at 0",
"Scores the legal-gate check below 2 because the CLA appears only in the pull request template rather than in the CONTRIBUTING file before the reader writes code",
"Scores the credit-and-next-step check below 2 because merged contributors are credited but never pointed at a concrete next issue",
"Returns a verdict line carrying blocking n/4 and scored n/16",
"Refuses to ship the new guide while blocking checks fail, and iterates rather than shipping with a caveat",
"States that a failed blocking check outranks every scored check",
"Produces the report in the prescribed shape: verdict, blocking checks table, scored checks table, funnel baseline, fix order, confounders",
"Ranks the fix order by damage removed per hour spent, letting effort break ties only among fixes of similar damage",
"Keeps this first score so the delta after the fixes is measurable"
]
},
{
"id": 9,
"prompt": "One of our maintainers raised contributor diversity at the Halyard (Ruby ORM) meeting. Someone pushed back with a study saying women's pull requests actually get merged more often than men's - 78.7% versus 74.6% - so there's no bias problem here and we should spend the effort elsewhere. I don't know the paper. Is that right, and does it change anything about how we handle outside pull requests?",
"expected_output": "The correct restriction of the cited figures to outside contributors, the study's caveats, and a concrete process control for reviewing outside pull requests.",
"files": [],
"expectations": [
"Identifies the study as Terrell et al., PeerJ Computer Science 3:e111 (2017), covering 3,064,667 pull requests",
"Confirms the 78.7% versus 74.6% figures describe the overall population, not the population this contribution path serves",
"Gives the restricted figures for outside contributors with an identifiable gender: women 58% against men 61%",
"Notes that contributors whose profiles were gender-neutral had the highest merge rate of all",
"States the caveats: gender was inferred, only 35.3% of users were linkable, and the study predates many platform changes",
"Says the direction is robust while the exact percentages are not",
"Concludes that 'therefore there is no bias problem' does not follow, because the reversal appears exactly on outside contributions",
"Prescribes reviewing against the written scope rule and the fixed review order rather than against an impression of the person, as the cheapest available control",
"Notes the project needs a published scope rule and a fixed review order for that control to exist at all",
"Raises information-foraging cost - having to hunt for the process - as unevenly distributed across newcomers, citing the GenderMag work on cognitive-style barriers",
"Does not present the overall 78.7% and 74.6% figures as the answer to the question asked"
]
},
{
"id": 10,
"prompt": "Three months after we fixed the contributing path on Lumenstack, our open-source feature store. Before: 2 external contributors in Q1, 1 in Q2. After: 5 in Q3. Median first response went from 11 days to 2. We also got written up in a popular newsletter in August, and I gave a conference talk in September. My VP wants a one-slide dashboard proving the work paid off. Can you build it?",
"expected_output": "A refusal to read a trend at this volume, the confounders named, and a small set of correctly-defined signals with their windows and caveats stated.",
"files": [],
"expectations": [
"Declines to present these numbers as a proven trend, stating that at this volume they are anecdotes with dates attached rather than a dashboard",
"Names the newsletter write-up and the conference talk as confounders that move these numbers more than a documentation change does",
"Requires the ship date of each change to be recorded and the confounders annotated before any delta is read",
"Reports second-contribution rate within 90 days as the retention number the whole path exists to move",
"Identifies the 90-day window as this skill's own default rather than a published standard",
"Excludes bot replies from median time to first human response",
"Compares that median against the 48-hour reference point and attributes it to practitioner guidance with no published dataset behind the figure",
"Tracks external first-pull-request merge rate and median time to merge separately from maintainers' own pull requests",
"Explains that maintainers' own pull requests are always faster and hide the number that matters",
"Tracks contributor absence factor and states it should rise slowly, as the only signal here measuring whether the project got less fragile",
"Tracks setup support load - issues and messages that are really 'I could not build it' - as the fastest-visible win",
"Warns against quoting another project's outcome figure in place of measuring this project's own funnel"
]
},
{
"id": 11,
"prompt": "Big ask, sorry. Meridian Forge is our open-source workflow engine, around 30 incoming issues a week. I want you to: (a) design the whole triage rota and label taxonomy so issues get sorted, (b) decide whether we switch from our CLA to a DCO, (c) write the maintainer promotion ladder and voting rules, and (d) fix the part where first-time contributors can never figure out where to start. Do all four.",
"expected_output": "Three of the four asks routed to the skills that own them, with only the first-contribution path worked, starting from a baseline.",
"files": [],
"expectations": [
"Routes the triage rota and label taxonomy to samber/developer-relations-skills@oss-issue-triage instead of designing them",
"Routes the CLA-versus-DCO decision to samber/developer-relations-skills@oss-license-strategy instead of choosing",
"Routes the promotion ladder and voting rules to samber/developer-relations-skills@oss-governance instead of writing them",
"Keeps the first-contribution path in scope and works it",
"Keeps the placement of the legal gate inside the CONTRIBUTING file in scope even while routing the choice itself away",
"Notes that the CNCF encourages projects to use a DCO as it is easier to set up and use, and attributes it as foundation policy rather than a measured friction study",
"Says a sign-off line such as `git commit -s` costs a contributor nothing while a signing workflow stops a typo fix",
"Links the governance document from the CONTRIBUTING file rather than reproducing the ladder inside it",
"Warns against copying a large project's process at this project's scale - take the shape, not the scale",
"Starts the in-scope work from a baseline measurement rather than from proposals"
]
},
{
"id": 12,
"prompt": "Here's the repo for Ashgrove, our Kotlin serialization library - go read it and just write me the full contributor onboarding plan. I don't have time for a back-and-forth, and I need it before our 1.0 release on November 14. Assume standard best practice for anything you need.",
"expected_output": "A held draft, a gating interview run one question at a time, and an explicit statement of how the deadline reorders the work.",
"files": [],
"expectations": [
"Refuses to draft any file before the gating interview questions are answered",
"Asks one question at a time rather than presenting a full questionnaire at once",
"Skips any question it can answer itself by reading the repository",
"Asks which kind of contribution the maintainer actually wants more of: code, documentation and translation, triage and support, or co-maintainers who can share the load",
"Asks whether the project is volunteer or solo-maintained, corporate-backed, or foundation-hosted, and connects the answer to the response target, the legal gate and the ladder",
"Asks how many hours per week the maintainer can realistically spend on contributors, review included, in a normal week rather than a good one",
"Asks what is out of scope, and records a blank answer as the audit's first finding rather than treating it as a blocker",
"Asks what happened the last three times an outsider tried to contribute - merged, stalled, declined, or vanished",
"Asks when the setup was last run from a clean machine",
"Asks who besides the maintainer can review a pull request, and what happens to contributors while they are away",
"Uses the November 14 deadline to promote fixes that land in an afternoon - the response target, the issue queue, the first reply - over environment tiers that need a rebuild, and says explicitly which answer moved what"
]
}
],
"trigger_queries": [
{ "query": "nobody contributes to my open source project", "should_trigger": true },
{ "query": "write a CONTRIBUTING.md for our repo", "should_trigger": true },
{ "query": "our good first issues get no takers", "should_trigger": true },
{ "query": "first-time contributors disappear after one PR", "should_trigger": true },
{ "query": "contributor onboarding for an open source library", "should_trigger": true },
{ "query": "how do we get more open source contributors", "should_trigger": true },
{ "query": "someone opened their first pull request and I don't know what to reply", "should_trigger": true },
{ "query": "we have 4k stars and zero external pull requests", "should_trigger": true },
{ "query": "audit why first-time contributors give up on us", "should_trigger": true },
{ "query": "our repo is lonely, just me committing for two years", "should_trigger": true },
{ "query": "should we label some issues as good first issue?", "should_trigger": true },
{ "query": "how do I make it easier for strangers to send us patches", "should_trigger": true },
{ "query": "people clone the repo and never come back", "should_trigger": true },
{ "query": "our setup instructions are probably broken but I can't tell", "should_trigger": true },
{ "query": "can you review our CONTRIBUTING file", "should_trigger": true },
{ "query": "we want to run Hacktoberfest this year, how do we prepare", "should_trigger": true },
{ "query": "is Google Summer of Code worth it for a two-person project", "should_trigger": true },
{ "query": "how long should we take to respond to an outside pull request", "should_trigger": true },
{ "query": "what should a beginner-friendly issue actually contain", "should_trigger": true },
{ "query": "we keep getting drive-by PRs that never turn into repeat contributors", "should_trigger": true },
{ "query": "how do I write a first issue that a stranger can actually finish", "should_trigger": true },
{ "query": "our external PRs show red CI and people give up", "should_trigger": true },
{ "query": "should we add a devcontainer so contributors can build the project", "should_trigger": true },
{ "query": "I want a path from stranger to merged PR", "should_trigger": true },
{ "query": "what stops people from sending us patches", "should_trigger": true },
{ "query": "our contributors vanish the moment I ask for changes", "should_trigger": true },
{ "query": "the bus factor on this project is 1 and I want to change it", "should_trigger": true },
{ "query": "I merged a first PR yesterday, what should I say to them", "should_trigger": true },
{ "query": "we need more people helping, not just watching", "should_trigger": true },
{ "query": "why do we get issues but never fixes", "should_trigger": true },
{ "query": "our good first issues are all claimed by people who vanished", "should_trigger": true },
{ "query": "how do I stop doing all the easy bugs myself", "should_trigger": true },
{ "query": "setup takes new people a week, what do I do about it", "should_trigger": true },
{ "query": "our project needs docs help but nobody ever offers", "should_trigger": true },
{ "query": "how do I measure whether our contribution path improved", "should_trigger": true },
{ "query": "score our repo on how welcoming it is to new contributors", "should_trigger": true },
{ "query": "first pull request experience", "should_trigger": true },
{ "query": "how do we handle a contributor who abandoned their PR halfway", "should_trigger": true },
{ "query": "I want to decline a PR without losing the person", "should_trigger": true },
{ "query": "we get lots of stars after every Hacker News post but the PR count never moves", "should_trigger": true },
{ "query": "where in our docs should the DCO sign-off be mentioned so people don't hit it at the very end", "should_trigger": true },
{ "query": "our CI needs secrets so fork PRs always fail red", "should_trigger": true },
{ "query": "how many beginner issues should we keep open at once", "should_trigger": true },
{ "query": "our contributing guide is 4000 words and nobody reads it", "should_trigger": true },
{ "query": "an AI agent opened a PR against our repo with the wrong branch name and commit format", "should_trigger": true },
{ "query": "make our repo easier to contribute to", "should_trigger": true },
{ "query": "what's the first thing to fix if we want outside help", "should_trigger": true },
{ "query": "we tried a contribution sprint at a conference and got nothing out of it", "should_trigger": true },
{ "query": "what should happen in the first 48 hours after someone opens a PR", "should_trigger": true },
{ "query": "our README is fine but people still can't contribute", "should_trigger": true },
{ "query": "we need a plan to turn users into contributors", "should_trigger": true },
{ "query": "check whether a stranger could build our project from a clean laptop", "should_trigger": true },
{ "query": "how do I write issues that teach instead of just being small", "should_trigger": true },
{ "query": "is our contribution process broken or is the project just niche", "should_trigger": true },
{ "query": "we lose people somewhere between cloning and opening a PR", "should_trigger": true },
{ "query": "help me stock a beginner issue queue", "should_trigger": true },
{ "query": "our mentorship intern never contributed again after the program ended", "should_trigger": true },
{ "query": "should we buy a mentorship program or fix something else first", "should_trigger": true },
{ "query": "our first-time contributors say they couldn't get the tests to pass", "should_trigger": true },
{ "query": "design the review loop for outside pull requests", "should_trigger": true },
{ "query": "how do I credit people who help without writing code", "should_trigger": true },
{ "query": "we want contributions from translators and doc writers too", "should_trigger": true },
{ "query": "our response time to outsiders is embarrassing, what number do we publish", "should_trigger": true },
{ "query": "walk our contribution path and tell me where it leaks", "should_trigger": true },
{ "query": "I have two hours a week for contributors, what do I do with them", "should_trigger": true },
{ "query": "how do we keep the contribution path from rotting after we fix it", "should_trigger": true },
{ "query": "we announced that we welcome contributions and nothing happened", "should_trigger": true },
{ "query": "what goes wrong between a stranger reading our README and sending code", "should_trigger": true },
{ "query": "our project gets forks but no pull requests back", "should_trigger": true },
{ "query": "eleven days of silence on a newcomer's PR, how bad is that", "should_trigger": true },
{ "query": "design an issue triage system our maintainer team can sustain", "should_trigger": false },
{ "query": "what label taxonomy should we use for incoming issues", "should_trigger": false },
{ "query": "set response targets for our issue backlog sized to our real capacity", "should_trigger": false },
{ "query": "should we pick MIT or AGPL for this project", "should_trigger": false },
{ "query": "DCO or CLA, which one should we adopt", "should_trigger": false },
{ "query": "write our GOVERNANCE.md with maintainer promotion rules", "should_trigger": false },
{ "query": "how do we decide who becomes a maintainer", "should_trigger": false },
{ "query": "rewrite our README so people understand what the project does", "should_trigger": false },
{ "query": "our README's hero section buries the install command", "should_trigger": false },
{ "query": "write a quickstart that gets a user to their first successful API call", "should_trigger": false },
{ "query": "audit our quickstart, users drop off at step 3", "should_trigger": false },
{ "query": "write our code of conduct and the enforcement ladder behind it", "should_trigger": false },
{ "query": "we had a harassment incident in our Discord, what's the playbook", "should_trigger": false },
{ "query": "plan the launch of our new open source project", "should_trigger": false },
{ "query": "how do we land on the front page of Hacker News for our launch", "should_trigger": false },
{ "query": "map the developer journey from discovery to advocacy", "should_trigger": false },
{ "query": "set up GitHub Sponsors tiers and rewards for our project", "should_trigger": false },
{ "query": "which open source projects should our company fund this year", "should_trigger": false },
{ "query": "design a developer ambassador program with perks", "should_trigger": false },
{ "query": "turn this release's commits into changelog entries", "should_trigger": false },
{ "query": "write a tutorial teaching our SDK's core concept step by step", "should_trigger": false },
{ "query": "define the standards every code sample in our docs must meet", "should_trigger": false },
{ "query": "build a community health measurement framework for our Slack", "should_trigger": false },
{ "query": "what DevRel metrics should we report to the CEO", "should_trigger": false },
{ "query": "get our package listed in more registries and awesome lists", "should_trigger": false },
{ "query": "decide what we open source and what stays proprietary", "should_trigger": false },
{ "query": "plan a recurring meetup for our user group", "should_trigger": false },
{ "query": "which conferences should we sponsor next year and at what tier", "should_trigger": false },
{ "query": "turn my accepted talk abstract into a rehearsable outline", "should_trigger": false },
{ "query": "write a migration guide for our v3 breaking changes", "should_trigger": false },
{ "query": "audit our docs structure against Diátaxis", "should_trigger": false },
{ "query": "should we launch a Discord or a forum for our users", "should_trigger": false },
{ "query": "write the job posting and scorecard for a developer advocate", "should_trigger": false },
{ "query": "split our DevRel budget across events, content and community", "should_trigger": false },
{ "query": "benchmark a competitor's developer experience from public signals", "should_trigger": false },
{ "query": "plan a quarter of developer content with named owners", "should_trigger": false },
{ "query": "pick the value metric and tier ladder for our developer tool's pricing", "should_trigger": false },
{ "query": "open core or hosted open source, which business model fits us", "should_trigger": false },
{ "query": "write a case study about a customer's production deployment", "should_trigger": false },
{ "query": "prepare me for a podcast interview about our project", "should_trigger": false },
{ "query": "pitch our funding round to reporters on the infra beat", "should_trigger": false },
{ "query": "optimize my GitHub profile README and pinned repositories", "should_trigger": false },
{ "query": "make our API docs something a coding agent can integrate from unattended", "should_trigger": false },
{ "query": "write an engineering blog post about our storage rewrite", "should_trigger": false },
{ "query": "script a screencast demoing our CLI end to end", "should_trigger": false },
{ "query": "should we join the working group for this protocol spec", "should_trigger": false },
{ "query": "build our employer brand so engineers apply to us", "should_trigger": false },
{ "query": "find the keywords developers search when they hit our error message", "should_trigger": false },
{ "query": "fix indexability and canonicals on our versioned docs site", "should_trigger": false },
{ "query": "design a live demo that survives being run on stage", "should_trigger": false },
{ "query": "cut our developer audience into a few named, sized segments", "should_trigger": false },
{ "query": "turn our support tickets into troubleshooting and error-reference pages", "should_trigger": false },
{ "query": "should we build a certification program for our platform", "should_trigger": false },
{ "query": "decide whether to open a plugin API so partners can build on us", "should_trigger": false },
{ "query": "plan our bottom-up self-serve go-to-market motion", "should_trigger": false },
{ "query": "how much should we share publicly while we build this", "should_trigger": false },
{ "query": "instrument our docs and repos with a proper event taxonomy", "should_trigger": false },
{ "query": "build me a watch list of DevRel newsletters and podcasts", "should_trigger": false },
{ "query": "should DevRel report into marketing or engineering", "should_trigger": false },
{ "query": "design our whole developer relations program from scratch", "should_trigger": false },
{ "query": "onboard a new engineer onto our codebase in their first week", "should_trigger": false },
{ "query": "improve our product signup and activation flow", "should_trigger": false },
{ "query": "write an employee onboarding checklist for new hires", "should_trigger": false },
{ "query": "reduce drop-off in our SaaS onboarding funnel", "should_trigger": false },
{ "query": "help me contribute a fix to someone else's repository", "should_trigger": false },
{ "query": "open a pull request against upstream following their conventions", "should_trigger": false },
{ "query": "onboard our new enterprise customer onto the platform", "should_trigger": false },
{ "query": "write a runbook for onboarding a new service into our monitoring", "should_trigger": false },
{ "query": "our new hires take three months to ship their first commit", "should_trigger": false },
{ "query": "onboard a new dependency into our build system", "should_trigger": false }
]
}
references/contributing-file-outline.md›
# CONTRIBUTING file outline
## 1. Placement and precedence
- Valid locations: repository root, `docs/`, `.github/`.
- When several copies exist, GitHub displays `.github/` first, then the root, then `docs/`. Keep exactly one file; duplicates diverge silently.
- The file is surfaced automatically when someone opens an issue or a pull request, in the repository sidebar, and on the repository's contribute page. Assume the reader arrives mid-task, already typing - write for skimming, put the entry points near the top.
- An organization-level `.github` repository supplies defaults to every repository that has no file of its own. Useful for policy boilerplate; never a substitute for the per-project setup and first-issue sections.
## 2. Section-by-section outline
Order matters: each section answers the question the reader has at that moment, and a reader who cannot answer question N never reaches section N+1.
1. **Welcome and scope of contribution (3-5 lines).** Which kinds are wanted: code, documentation, tests, triage, translation, design, examples. Naming non-code work here is what recruits the majority of first-time contributors.
2. **Out of scope (3-6 lines).** Features outside the project's purpose, new dependencies, style rewrites, vendored platform support. Every line here prevents a PR that would have cost both sides a week and ended in a rejection.
3. **Ways to help without code (short list).** Reproducing bug reports, answering questions, improving error messages, adding a missing test. Link the label or query that surfaces each.
4. **Get the project running (the longest technical section).** One command from a fresh clone to passing tests, plus the expected output and the version file or container definition that pins the prerequisites. Anything the contributor must install by hand is a documented prerequisite, not an assumption.
5. **Find something to work on.** The beginner-issue query, the claiming convention, the expiry rule for stale claims, and what to do when nothing fits.
6. **Before you open a pull request.** The gating commands, the branch to target, the commit-message convention with one example, and the legal step (DCO sign-off or CLA) stated here rather than discovered at the gate.
7. **What happens after you submit.** Who reviews, the response target, what each label means, the merge style, which release the change ships in, and what happens when a PR goes quiet, from both sides.
8. **Getting unstuck.** The synchronous channel, the asynchronous channel, and the expected latency of each. A contributor stuck for two days who never asked is a contributor you lost to a missing link.
9. **Recognition and growing into the project.** How contributions are credited, and what the next rungs are. Keep it to a pointer if a governance document owns the full ladder.
## 3. Sizing by project shape
The advice diverges most between a volunteer project and a corporate-backed one, so state which you are - contributors calibrate their expectations from it.
| | Volunteer / solo maintainer | Corporate-backed or foundation project |
| -------------------------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| Response target to publish | Honest and generous ("usually within a week"), plus the real hours-per-week budget | A staffed target, with the on-call or triage rota named |
| Legal gate | Usually DCO sign-off, one line | Often a CLA; link it and say when it triggers |
| Scope negotiation | Ask before large work, always | Often a design-doc or RFC process to link |
| Ladder | Repeat contributor → co-maintainer, informal | Published ladder with sponsors, areas, and emeritus rules |
| Risk to name | Maintainer burnout; say no early | Contributor suspecting the roadmap is decided internally; publish the decision process |
Everything else - setup, first issues, pre-PR checks, review tone, recognition - is identical in both shapes. Say so rather than writing two documents.
Length: a small library is complete at roughly 150-300 words plus the setup block. A multi-repository project needs a short root file that routes to per-area guides, not one long file.
## 4. What belongs in a neighbouring file
Link each of these instead of duplicating its content:
- `README`: what the project is
- `CODE_OF_CONDUCT`: behaviour and enforcement
- `SECURITY`: private vulnerability reporting
- `SUPPORT`: where _users_ ask usage questions
- `GOVERNANCE`: decision rights and maintainer selection
- issue and PR templates: per-submission prompts
- `CODEOWNERS`: reviewer routing
A CONTRIBUTING file that absorbs its neighbours becomes the document nobody finishes.
## 5. Compact skeleton
```markdown
# Contributing to <project>
Thanks for being here. We take code, documentation, tests, triage and translations.
We do not take <the two or three things that get declined>.
## Set up
git clone <fork> && cd <project>
make setup # installs everything and runs the test suite
Expect: `<N> tests passed` in under <M> minutes.
Prerequisites: <runtime> <version> (pinned in `<version file>`), <system package>.
## Find something to work on
- Beginner-friendly: <link to the label query>. Comment on the issue to claim it;
claims expire after <N> days.
- Nothing fits? Open an issue describing what you want to change before writing code.
## Before opening a pull request
make test lint
Target the `<branch>` branch. Sign your commits with `git commit -s` (DCO).
## After you submit
A maintainer responds within <target>. We squash-merge. Changes ship in the next
<cadence> release, and you are credited in the changelog.
## Stuck?
Ask in <channel> (usually answered within <latency>) or comment on your pull request.
```
## 6. Legibility to an agent-assisted contributor
Some first pull requests now arrive prepared by a coding agent reading this file on the contributor's behalf. GitHub's own `make-repo-contribution`, a widely installed skill on skills.sh, searches the README, the CONTRIBUTING file, project documentation, and the issue and PR templates _before_ the first branch. It applies exactly six things:
- branch naming
- commit message format
- which template to use
- required reviewers
- whether an issue must precede the pull request
- the prerequisite build/lint/test commands
Anything the project leaves unstated is replaced by that skill's own generic templates: an unstated convention is not merely undiscovered, it is overwritten.
Three consequences for how the file is written:
- **State conventions literally, near the top.** A branch prefix or commit format published only inside a PR template is found after the commits already exist.
- **Write the commands out, not just the wrapper.** The same skill refuses to execute anything it finds in repository documentation and asks the human to run and confirm builds and tests instead. `make setup` alone is not enough; give the literal commands and the output that proves they worked.
- **Never put a required step behind an off-repo link.** The agent is instructed not to fetch URLs mentioned in repository docs. Anything mandatory belongs in the file itself.
The same posture the skill sets for itself - "you are a guest in someone else's repository" - is a usable line for a project's own guidance.
references/contributor-path-scorecard.md›
# Contributor path scorecard
Score before changing anything, and again at the end.
## 1. Blocking checks
Four checks, pass or fail. A fail here outranks every scored check, because each one ends the first contribution outright.
| # | Check | Passes when |
| --- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| B1 | Contribution is invited | A CONTRIBUTING file exists in a location the forge surfaces, and states which kinds of contribution are accepted |
| B2 | The documented setup runs | A cold run reaches passing tests using only the written steps, with no undocumented step |
| B3 | There is work available | At least three unclaimed, currently-valid beginner-friendly issues exist, each with a body a stranger could act on |
| B4 | Submissions get answered | The median time to first human response on externally-opened issues and PRs over the last 90 days is inside the published target |
B4 cannot be faked by publishing a slower target and then meeting it - if the honest target is two weeks, say so, and note it as a finding rather than a pass in disguise.
## 2. Scored checks
Eight checks, 0-2 points each, 16 total:
- 2: evidence you can point at
- 1: partial
- 0: absent
| # | Check | 2 points |
| --- | --------------------------- | ------------------------------------------------------------------------------------------------------------- |
| S1 | Out-of-scope is stated | A reader can predict which PRs get declined without asking |
| S2 | Prerequisites are pinned | Runtime and tool versions are pinned in a version file or container definition, not prose |
| S3 | Local gates match CI | Every check CI enforces is runnable locally with a documented command |
| S4 | Fork CI is useful | A credential-free lane runs on fork PRs and goes green; nothing red is unfixable by the contributor |
| S5 | First issues are complete | Beginner issues carry expected behaviour, location, required skills, verification command, and a named mentor |
| S6 | Claiming is defined | The claim convention and the stale-claim expiry are written down and applied |
| S7 | Legal gate is pre-announced | DCO or CLA appears in CONTRIBUTING before the reader writes code |
| S8 | Credit and next step | Merged contributions are credited, and the contributor is pointed at a concrete next issue |
## 3. Cold-run protocol
The only way to score B2 honestly. Reasoning about the instructions does not count.
1. Start clean: a fresh container, a new user account, or a machine that has never built this project. No warm caches, no global config, no credentials you forgot you have.
2. Read only what a stranger reads - the README and the CONTRIBUTING file. Do not use repository knowledge you already hold.
3. Execute the written steps literally, in order. When a step fails, record the failure and the fix, then continue.
4. Record wall-clock time to the first passing test run.
5. Log every undocumented requirement: system package, environment variable, running service, credential, minimum resource, platform assumption.
6. Fix the documentation, then run the whole sequence again from clean. Repeat until nothing is discovered.
If you cannot execute commands in your environment, say so plainly and ask the maintainer to run the sequence and paste the full output - including the failures. Do not mark B2 passed by inspection.
Second cold run, same discipline, for the task path: from the beginner-issue list, can a stranger pick an issue, understand what is being asked, and locate the file to change in under 15 minutes without asking a question?
## 4. Pass threshold
The path passes when all four blocking checks pass and the scored checks total at least 12 of 16.
No published rubric scores a first-contribution path, so that mark is this skill's own baseline, not a finding - say so when a maintainer asks where the number comes from, and let a project set a different bar with a stated reason. The two numbers inside the rubric that are sourced are B4's 48-hour reference point (GitHub Open Source Guides) and the CHAOSS definitions behind the funnel baseline; `published-findings.md` carries the full published-versus-self-set split.
Below the threshold, iterate rather than shipping with a caveat. Re-score after each round of fixes, and keep the first score - the delta is the only evidence the work changed anything.
## 5. Report format
Produce this shape verbatim, with evidence attached to every line.
```markdown
# Contributor path audit - <project> - <date>
## Verdict
<PASS | FAIL> - blocking: <n>/4 passed, scored: <n>/16
## Blocking checks
| Check | Result | Evidence |
| ----------------------- | ------ | -------------------------------------------------------- |
| B1 Contribution invited | PASS | `.github/CONTRIBUTING.md`, lines 1-12 |
| B2 Setup runs cold | FAIL | Cold run stopped at `make setup`: `libpq-fe.h not found` |
| ... |
## Scored checks
| Check | Score | Evidence | Fix |
| ---------------------- | ----- | ------------------------------------------------------------- | ------------------------------------------- |
| S1 Out of scope stated | 0 | No scope section; 3 of the last 10 PRs closed as out of scope | Add scope section naming those 3 categories |
| ... |
## Funnel baseline
- New external contributors, last 4 quarters: <n, n, n, n>
- Second-contribution rate within 90 days: <n%>
- Median time to first response, external issues/PRs: <n days>
- External first-PR merge rate: <n%>
- Contributor absence factor: <n>
## Fix order
1. <highest-damage fix, with the check it unblocks>
2. ...
## Confounders
<launches, conference talks, mentions that moved these numbers independently>
```
Rank fixes by damage removed per hour spent, and let effort break ties only among fixes of similar damage. A failed blocking check outranks every scored one. A setup that fails on a common platform outranks every wording improvement in the file, however fast the wording is to rewrite: cheap and efficient are different orderings, and only the second one answers what to do first.
references/first-issue-and-review-examples.md›
# Worked examples: first issues and first-PR replies
Copy the shape, not the wording.
## Table of Contents
- [1. Beginner-friendly issue body](#1-beginner-friendly-issue-body)
- [2. First response on a new PR](#2-first-response-on-a-new-pr)
- [3. Review comments](#3-review-comments)
- [4. Declining a contribution](#4-declining-a-contribution)
- [5. Merge message](#5-merge-message)
- [6. Re-inviting a stalled contributor](#6-re-inviting-a-stalled-contributor)
## 1. Beginner-friendly issue body
**Weak**
```
Title: Improve error handling in the config loader
Labels: good first issue
The config loader should handle errors better.
```
Nothing here tells a stranger what "better" means, where the loader lives, how to verify a fix, or who to ask. It is small for the maintainer, who already knows all four.
**Strong**
```
Title: Config loader reports "unexpected error" when the config file is missing
Labels: good first issue, area/config, skills/file-io
**Current behaviour**
Running `app start` without `config.yaml` prints `unexpected error` and exits 1.
**Expected behaviour**
Print `config file not found: <path> - create one with 'app init'` and exit 1.
**Where**
`internal/config/loader.go`, `Load()`, around the `os.ReadFile` call.
Tests live in `internal/config/loader_test.go`.
**Suggested approach**
Check for a not-exist error from the read and return a typed error carrying the
path. The message text above is settled - no design discussion needed.
**Verify**
`make test PKG=./internal/config` - add a case covering the missing-file path.
**Mentor**
@maintainer-handle. Comment here to claim it; ask anything in the issue thread.
```
The additions that matter most: the skill label (`skills/file-io`) so a contributor can judge fit before committing, the explicit "no design discussion needed", and the named mentor.
## 2. First response on a new PR
**Weak**
Silence for eleven days, then: `Please rebase and fix the failing tests.`
**Strong**, posted the same day:
```
Thanks for this - it is in scope and the approach looks right.
I will do a full review by Thursday. Two things in the meantime:
- CI shows red on `lint` only; run `make lint` locally and it should reproduce.
- The other two red checks need repository secrets and cannot run on a fork.
Ignore them; I will run them before merge.
```
This is the reply the 48-hour finding is about - acknowledgement, not a completed review.
## 3. Review comments
**Weak**
```
This is wrong.
Use a pointer here.
Nit: spacing.
Why did you do it this way?
```
Four unlabelled comments, one of them a formatting issue a machine should have caught, and no way for the contributor to tell which one blocks the merge.
**Strong**
```
**Blocking** - this drops the error when the file exists but is unreadable
(permissions). Wrapping it keeps the cause visible for the caller:
`return fmt.Errorf("read config %s: %w", path, err)`
**Blocking** - please add a test for the unreadable-file case next to the
missing-file one you added; it is the branch we regress most often.
**Optional** - we usually name these `errConfigMissing` rather than `ErrMissing`,
but the existing package is inconsistent, so either is fine here.
Formatting is handled by `make fmt`; ignore anything the diff shows there.
```
Each request carries its reason, and style is delegated to the formatter.
## 4. Declining a contribution
**Weak**: closing with no comment, or leaving the PR open for six months.
**Strong**
```
Thank you for writing this, and I am sorry it is a no. Plugin loading is outside
what this library covers - CONTRIBUTING lists it under "out of scope" because it
would pull in a dependency we keep the project free of.
The change itself is clean, and it would work well as a separate package; happy
to link it from the README if you publish it.
If you want another way in, #412 is open and close to what you did here.
```
One or two sentences would be enough - what matters is that it happens quickly rather than by expiry.
## 5. Merge message
**Weak**: merge, no comment.
**Strong**
```
Merged - thank you. This ships in 2.4.0 next Tuesday and you are credited in the
changelog entry.
If you want a second one, #388 is the same area and slightly deeper: it needs the
same error type applied to the loader's watch path. Happy to mentor it.
```
## 6. Re-inviting a stalled contributor
**Weak**: an automated stale bot closing the PR at 30 days with a templated message.
**Strong**
```
Checking in - no pressure, and no deadline on my side. Three options:
1. You finish it when you have time; say the word and I will hold it open.
2. I push the last two commits myself (edits are enabled) and you stay the author.
3. We close it and I open an issue with what is left.
Any of the three is a good outcome. Which do you prefer?
```
An abandoned PR is usually a life event, not a lost interest. Offering to finish it keeps both the change and the contributor.
references/published-findings.md›
# Published findings on contributor onboarding
Published figures on newcomer onboarding with their methodological caveats, plus the baselines this skill sets itself. Read this before quoting any figure to a maintainer.
## 1. Published figures
| Claim used in the skill | Source | Caveat |
| ------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| Contributors reviewed within 48 hours return at a much higher rate; "it only takes one negative experience to make someone not want to come back" | GitHub Open Source Guides, <https://opensource.guide/building-community/> | Practitioner guidance, no published dataset behind the 48-hour figure |
| Newcomer barriers fall into five categories: social interaction, prior knowledge, finding a way to start, documentation, technical hurdles | Steinmacher et al., _A systematic literature review on the barriers faced by newcomers to open source software projects_, Information and Software Technology 59 (2015) | Literature review over 20 primary studies, not a measurement of any one project |
| Newcomers choose issues labelled by the API domain required more often than by architecture area | Steinmacher et al., arXiv:2103.12653 | 74 participants, single study |
| `good first issue` means members committed to extra assistance; `help wanted` is the broader signal | <https://www.kubernetes.dev/docs/guide/first-contribution/> | Project-specific convention, widely copied |
| GitHub surfaces the `good first issue` label algorithmically and publishes no criteria for it | <https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/encouraging-helpful-contributions-to-your-project-with-labels> | - |
| "The hard part of getting into open source for the first time isn't the implementation of a feature, but figuring out how to actually contribute code." | Kent C. Dodds, _First Timers Only_, <https://kentcdodds.com/blog/first-timers-only> | Opinion piece that launched the `first-timers-only` label convention |
| CNCF "encourage[s] projects to use DCO as it's easier to setup and use" | <https://github.com/cncf/foundation/issues/130> | Foundation policy, not a measured friction study |
| A CLA "creates friction for new contributors: someone who wants to fix a typo must first complete a signing workflow" | <https://tenthirtyam.org/dispatches/2026/04/08/dco-vs-cla-managing-contribution-agreements-in-open-source/> | Practitioner post |
## 2. Self-set baselines
The following numbers are self-set defaults, not published standards. State them as such when a maintainer asks where they come from, and let a project override any of them with a reason.
- The scorecard's pass mark (all four blocking checks, plus 12 of 16 scored points).
- A standing stock of at least three valid unclaimed beginner issues.
- Sizing a first issue at roughly one evening of work, setup included.
- The 15-minute ceiling for a stranger locating the file to change during the task-path cold run.
- A quarterly re-audit cadence.
- The 90-day window used for "second-contribution rate".
Two thresholds used alongside them are published rather than self-set: the 48-hour review window comes from the Open Source Guides, and the CHAOSS metric definitions (time to first response, contributor absence factor, new contributors) come from the CHAOSS project.
## 3. Structured mentorship programs
A maintainer can host a newcomer cohort instead of building one. Program terms as each program publishes them:
| Program | Stipend | Duration | Eligibility | Published outcome |
| --------------------- | ------------------------------------------ | --------------------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Google Summer of Code | $750–$6,600, purchasing-power adjusted | 8–22 weeks (12 standard) | 18+, any newcomer since 2022 | 63.5% of 2,456 studied participants opened a PR to the same project after the program; 85.74% of GSoC PRs merged (arXiv:2412.13120) |
| Outreachy | $7,000 flat | 3 months | People facing underrepresentation or bias in tech | 80% still contributing (2019 alum survey, 37% response rate) |
| LFX Mentorship | $1,000–$6,600, purchasing-power adjusted | 12 weeks full-time / 24 part-time | Varies, often first-timers | 270+ graduates since 2019 |
| MLH Fellowship | up to $5,000, need-based | 12 weeks | Students, graduates, non-traditional | Not published; pods of 8–10 with a mentor |
| Season of Docs | $5,000–$15,000 granted to the organization | 3–5 months | Organizations apply and hire the writer | Per-project case studies |
Sources: developers.google.com/open-source/gsoc, outreachy.org, docs.linuxfoundation.org/lfx/mentorship, developers.google.com/season-of-docs.
**The counter-case.** Hacktoberfest rewarded pull-request volume with a T-shirt and produced a 2020 spam wave severe enough that DigitalOcean made participation opt-in per repository, shortened the grace period, banned repeat spammers and dropped the T-shirt entirely in 2023 (<https://developerrelations.com/case-studies/overcoming-hacktoberfest-spam/>). An extrinsic reward with no quality gate buys volume, and volume is not what a thin review queue needs.
## 4. Whether programs work at all
The two most-cited studies disagree, and neither used a matched control group:
- The GSoC PR study (arXiv:2412.13120) found 63.5% post-program continuation.
- Labuschagne & Holmes, _Do Onboarding Programs Work? A Multi-Level Empirical Analysis of the Effect on Mozilla Contributor Activity_ (MSR 2015, DOI 10.1109/MSR.2015.49), found the opposite direction: "developers whose initial contribution is on a GFB [good-first-bug] or mentored bug are less likely to become long-term contributors", concluding "these programs alone do not automatically improve the odds."
- Silva et al. (arXiv:1910.05798, 141 students / 53 mentors) add the motivational reading: "students enter GSoC for an enriching experience, not necessarily to become frequent contributors."
Treat "an onboarding program improves retention" as unproven in the general case. Prefer a process metric the project can measure on its own funnel (time to first response, second-contribution rate) over importing another project's self-reported outcome. Say this out loud to a maintainer who wants to buy a program instead of fixing the path.
## 5. Bias in first-PR acceptance
Terrell et al., _Gender differences and bias in open source: pull request acceptance of women versus men_ (PeerJ Computer Science 3:e111, 2017, DOI 10.7717/peerj-cs.111), analysed 3,064,667 pull requests and linked 35.3% of users to a gender.
- Overall, women's PRs merged at a higher rate than men's: 78.7% vs 74.6%.
- Restricted to **outside contributors with an identifiable gender**, women dropped to 58% vs men's 61%, while contributors whose profiles were gender-neutral had the highest rate of all (70% women, 65% men).
- Authors' conclusion: "although women on GitHub may be more competent overall, bias against them exists nonetheless."
- Caveat: gender was inferred from name and Google+ profile linkage, only 35.3% of users were linkable, and the study predates many platform changes. The direction is robust; the exact percentages are not.
Related: Steinmacher et al. (arXiv:2301.10912) used GenderMag to find cognitive-style barriers in GitHub's own interface and measured improved task performance and self-efficacy after redesign, mainly for people with cognitive styles more common among women. Information-foraging cost - having to hunt for the process - is not distributed evenly across newcomers.
Reach-focused initiatives are measured differently again: Django Girls reports 1,137 workshops in 593 cities reaching 24,500+ women by 2024, with 71.2% of surveyed alums continuing to learn to code and 44.7% starting work in tech - self-reported, subset response (<https://www.djangoproject.com/foundation/reports/2024/>).
## 6. Cloud development environments
Devcontainer-based cloud workspaces (Codespaces, Gitpod, DevPod, Coder) are the strongest available fix for "setup takes a week", but every published time saving is vendor-reported: prebuilds cutting startup "from 3-5 minutes to 10-30 seconds", onboarding "from one to two weeks down to near-instant". Treat those numbers as marketing figures, not measurements.
Three constraints to raise before recommending one:
- **Who pays for compute.** Free personal allotments are small, and storage bills even while a workspace is stopped. Without an org-billed plan or a sponsor, the free tier caps how much a newcomer can experiment.
- **Portability before hosting.** `.devcontainer/` is shared across VS Code Dev Containers, Codespaces and DevPod; the vendor is not. Adopt the config first, the host second. Gitpod dropping its self-hosted option in 2024 is the cautionary case for hard-coding a vendor's terms into contributor docs.
- **Drift.** A cloud environment maintainers never use bit-rots. Make the devcontainer the canonical environment for everyone, and keep local setup a first-class path for contributors with poor connectivity to the vendor's regions.
## 7. Onboarding events and sprints
- PyCon US runs up to four days of post-conference sprints, free with registration, preceded by a ~3-hour "Introduction to Sprinting" workshop covering git, virtual environments and pull requests.
- pyOpenSci's sprint handbook (<https://www.pyopensci.org/handbook/community/events/sprints.html>) prescribes the operational spine:
- pre-tag `sprintable` issues before the event
- track output on a per-event board
- count issues closed and PRs merged
- follow up with attendees afterwards
- Kubernetes ran the most resourced program in the field - a ~5-hour New Contributor Workshop with a dedicated contributor-playground repository - and then stopped: "running the session during the summit never led to any people who weren't already contributing to the project becoming dedicated contributors" (<https://kubernetes.io/blog/2023/11/03/k8s-contributor-summit-behind-the-scenes/>). It was replaced in September 2024 by a monthly online New Contributor Orientation, overview-only.
scripts/contributor-path-audit.sh›
#!/usr/bin/env bash
# Reports the mechanical facts about a repository's first-contribution path.
# Usage: contributor-path-audit.sh [repo-root]
# Reports facts only, never judgements. Requires git and standard POSIX tools.
# Requires: bash 3.2+ (macOS default) or bash 4/5 (Linux), plus git 2.6+ (for
# `git log --date=format:`), grep, find, wc, tr, awk, sort, uniq, sed, ls.
# Portable across macOS (BSD userland) and Linux (GNU coreutils): uses POSIX
# regex classes and no GNU-only flags.
set -uo pipefail
ROOT="${1:-.}"
cd "$ROOT" 2>/dev/null || { echo "cannot enter $ROOT" >&2; exit 1; }
hr() { printf '\n== %s ==\n' "$1"; }
found() { printf ' %-28s %s\n' "$1" "$2"; }
hr "COMMUNITY HEALTH FILES"
# GitHub display precedence when duplicated: .github/ then root then docs/.
for base in CONTRIBUTING CODE_OF_CONDUCT SECURITY SUPPORT GOVERNANCE; do
hits=""
for dir in .github . docs; do
for ext in "" .md .rst .txt; do
f="$dir/$base$ext"
[ -f "$f" ] && hits="$hits ${f#./}"
done
done
if [ -z "$hits" ]; then
found "$base" "MISSING"
else
set -- $hits
found "$base" "$hits${2:+ <- precedence: $1}"
fi
done
if [ -f CODEOWNERS ] || [ -f .github/CODEOWNERS ] || [ -f docs/CODEOWNERS ]; then
found "CODEOWNERS" "present"
else
found "CODEOWNERS" "MISSING"
fi
if [ -d .github/ISSUE_TEMPLATE ]; then
found "issue templates" "$(find .github/ISSUE_TEMPLATE -type f | wc -l | tr -d ' ') file(s)"
else
found "issue templates" "MISSING"
fi
ls .github/PULL_REQUEST_TEMPLATE* .github/pull_request_template* >/dev/null 2>&1 \
&& found "PR template" "present" || found "PR template" "MISSING"
hr "CONTRIBUTING CONTENT PROBE"
CFILE=""
for dir in .github . docs; do
for ext in .md .rst .txt ""; do
[ -z "$CFILE" ] && [ -f "$dir/CONTRIBUTING$ext" ] && CFILE="$dir/CONTRIBUTING$ext"
done
done
if [ -z "$CFILE" ]; then
echo " no CONTRIBUTING file to probe"
else
echo " file: ${CFILE#./} ($(wc -w < "$CFILE" | tr -d ' ') words, $(wc -l < "$CFILE" | tr -d ' ') lines)"
probe() { grep -qiE "$2" "$CFILE" && found "$1" "mentioned" || found "$1" "NOT FOUND"; }
probe "types of contribution" "documentation|translat|triage|non-code|design"
probe "out of scope / vision" "out of scope|not accept|scope|roadmap|vision"
probe "environment setup" "install|setup|bootstrap|dependenc|make |npm |pip |cargo |go mod"
probe "run the tests" "test|spec|pytest|jest|go test|cargo test"
probe "finding work" "good first issue|help wanted|first-timers|pick an issue|claim"
probe "branch / commit rules" "branch|commit message|conventional|squash|rebase"
probe "legal gate (DCO/CLA)" "sign-off|signed-off|dco|cla|contributor license"
probe "review expectations" "review|maintainer will|respond|business day|within [0-9]"
probe "where to ask" "discord|slack|matrix|discussion|mailing list|forum|irc"
probe "code of conduct link" "code of conduct|conduct.md"
fi
hr "SETUP SURFACE"
for f in Makefile Taskfile.yml justfile script/bootstrap scripts/setup.sh \
.devcontainer/devcontainer.json .devcontainer.json \
docker-compose.yml compose.yaml \
.nvmrc .python-version .tool-versions rust-toolchain.toml .ruby-version; do
[ -e "$f" ] && found "$f" "present"
done
[ -f Makefile ] && grep -oE '^[a-zA-Z0-9_.-]+:' Makefile | tr -d ':' | tr '\n' ' ' \
| sed 's/^/ make targets: /;s/$/\n/'
lock=$(ls package-lock.json yarn.lock pnpm-lock.yaml poetry.lock uv.lock Cargo.lock go.sum \
Gemfile.lock composer.lock 2>/dev/null | tr '\n' ' ')
found "lockfiles" "${lock:-NONE}"
hr "CI EXPOSURE ON FORK PULL REQUESTS"
wf=$(find .github/workflows .gitlab-ci.yml .circleci -type f 2>/dev/null | wc -l | tr -d ' ')
found "CI config files" "$wf"
if [ "$wf" != "0" ]; then
sec=$(grep -rlE 'secrets\.[A-Z_]|\$\{\{ *secrets' .github/workflows 2>/dev/null | wc -l | tr -d ' ')
found "workflows using secrets" "$sec (these cannot run on fork PRs)"
pt=$(grep -rl 'pull_request_target' .github/workflows 2>/dev/null | wc -l | tr -d ' ')
found "pull_request_target uses" "$pt (audit each: runs with write scope)"
fi
hr "CONTRIBUTOR HISTORY (git log, all time)"
if [ -d .git ]; then
[ -f .git/shallow ] && echo " WARNING: shallow clone, history numbers below are truncated"
git log --format='%aE' | tr 'A-Z' 'a-z' | sort | uniq -c | sort -rn > /tmp/.cpa_authors.$$
total_c=$(awk '{s+=$1} END {print s+0}' /tmp/.cpa_authors.$$)
total_a=$(wc -l < /tmp/.cpa_authors.$$ | tr -d ' ')
once=$(awk '$1==1' /tmp/.cpa_authors.$$ | wc -l | tr -d ' ')
found "commits" "$total_c"
found "distinct authors" "$total_a"
[ "$total_a" -gt 0 ] && found "one-commit-only authors" "$once ($((once * 100 / total_a))%)"
# Contributor absence factor: smallest author count covering 50% of commits (CHAOSS).
awk -v t="$total_c" '{c+=$1; n++} c*2>=t {print " absence factor (50% of commits): " n; exit}' /tmp/.cpa_authors.$$
echo " new authors per year (first commit):"
git log --reverse --format='%aE|%ad' --date=format:'%Y' \
| awk -F'|' '!seen[tolower($1)]++ {y[$2]++} END {for (k in y) print " " k ": " y[k]}' | sort
rm -f /tmp/.cpa_authors.$$
else
echo " not a git repository"
fi
hr "NOT COVERED HERE"
cat <<'EOF'
Time to first response, first-PR merge rate, and open good-first-issue stock
need the forge API. Collect them from the host's UI or API and record the date.
EOF
SKILL.md›
---
name: oss-contributor-onboarding
description: Designs and verifies the path a stranger walks to their first merged contribution on an open-source project - the CONTRIBUTING file, the good-first-issue queue, a clone-to-passing-tests command that works cold, and the first-pull-request review and recognition loop, scored against a blocking-plus-weighted rubric. Use whenever someone says "nobody contributes to my project", "write a CONTRIBUTING.md", "our good first issues get no takers", "first-time contributors disappear", "contributor onboarding", "first pull request experience", or "how do we get more open-source contributors" - even if they only complain about a lonely repo. Not triage-system design - use samber/developer-relations-skills@oss-issue-triage. Not governance or CLA choice.
license: MIT
metadata:
author: Samuel Berthe
version: "1.0.1"
---
# Contributor Onboarding
You are fixing the path between a stranger who wants to help and a merged pull request with their name on it. Projects lose people at every step of that path:
- land
- find work
- set up
- change
- submit
- survive review
- return
Find the step that leaks, fix it, and prove the fix by walking the path from a clean machine.
Diagnose against a published taxonomy, not intuition. Steinmacher et al.'s systematic review of newcomer barriers (Information and Software Technology 59, 2015, a review over 20 primary studies, not a measurement of any one project) sorts every recorded failure into five categories:
- social interaction
- the newcomer's prior knowledge
- finding a way to start
- documentation
- technical hurdles
Name the category behind each finding: it stops the audit from becoming a list of wording complaints.
Two failures dominate, and both are invisible from inside the project:
- A setup that breaks on a machine the maintainer never tested produces no issue, no message, and no trace.
- Silence on a submitted pull request produces the same nothing.
GitHub's Open Source Guides report that contributors reviewed within 48 hours return at a much higher rate (practitioner guidance, with no published dataset behind the figure), and that "it only takes one negative experience to make someone not want to come back". Optimize for those two failures before touching any wording.
Stay inside the first-contribution path. Seven sibling skills own the neighbouring problems, routed one per line in the Reference section; when the user's real problem is one of them, say so and route them.
## Invocation and output
Typical invocations, and what each one should produce:
| The user says | You run | You return |
| --------------------------------------------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| "audit why first-time contributors give up" | Steps 1-2, then score | The audit report in [./references/contributor-path-scorecard.md](./references/contributor-path-scorecard.md) section 5 |
| "write a CONTRIBUTING.md for this repo" | Steps 1-3, then 5 | A drafted file, plus the cold-run log that proves each command in it |
| "our good first issues sit untouched for months" | Step 1 baseline, then step 4 | A rewritten queue, a claiming convention, an expiry rule |
| "someone opened their first PR and I do not know what to reply" | Step 6 only | A reply drafted from the templates, plus the two-clock rule for the next one |
| "we get stars but no pull requests" | Full workflow | Scorecard first - this phrasing usually means step 3 or step 6, not the wording of any file |
Attach evidence to every deliverable:
- a file path and line
- a command output
- a counted number with its date
A recommendation with no evidence attached is an opinion, and a maintainer will discount it correctly.
## Interview
Ask one question at a time, multiple-choice where possible, and skip anything you can answer yourself by reading the repository. Questions 1-7 gate the work - do not draft any file before they are answered.
**Memory: Store a few info about the current task or project context. When memory lives in a file, use `devrel-context.md`; if a different memory system is in use, rely on that instead. Separate task info in different sections. Remove finished tasks. Add a date to a task; no date for general project context. Some interview responses may differ between 2 tasks.**
1. Which repository, and can I read it and run commands inside it?
2. What do you actually want more of: code contributions, documentation and translation help, triage and support help, or co-maintainers who can share the load?
3. Is this a volunteer or solo-maintained project, or is it corporate-backed or foundation-hosted? The answer changes the response target, the legal gate, and the ladder you can promise - the split is tabled in [./references/contributing-file-outline.md](./references/contributing-file-outline.md) §3.
4. How many hours per week can you realistically spend on contributors, review included, in a normal week rather than a good one? An honest small number is more useful than an aspiration, and it is the ceiling every later recommendation is sized against.
5. By what date must this land - a release, a grant milestone, an event, or an open horizon?
6. Do you want one wave of contributions, or a path that keeps producing contributors after you stop pushing it?
7. What is out of scope - the contributions you decline however well written?
8. What happened the last three times an outsider tried to contribute? Merged, stalled, declined, vanished?
9. Is there a legal gate (DCO sign-off, CLA), and does the contributor learn about it before or after opening the pull request?
10. How long does a stranger's setup take today, and when did you last run it from a clean machine?
11. Does anything about your stack make setup unusually hard - a database, a paid API key, a GPU, a proprietary SDK?
12. Who besides you can review a pull request, and what happens to contributors while you are on holiday?
Record a blank on question 7 as the audit's first finding, not a blocker.
Carry questions 4, 5 and 6 into every ordering in this skill, and say which answer moved what:
- a near deadline (Q5) promotes the fixes that land in an afternoon, the response target, the issue queue, the first reply, over the environment tiers that need a rebuild
- a compounding mandate (Q6) promotes step 3, the only work that keeps paying after you stop
- hours per week under a day (Q4) delete the structured program in step 7 outright, whatever its appeal
## Step 1 - Baseline before changing anything
Measure first, so the work has a before and an after that are not both opinion.
1. Run `scripts/contributor-path-audit.sh <repo-root>`. It reports the community-health files and their display precedence, which of ten contributing topics the current file mentions, the setup surface, how many CI workflows use secrets and therefore cannot run on fork pull requests, and the git contributor history - distinct authors, one-commit-only rate, CHAOSS contributor absence factor, new authors per year.
2. Treat the script's content probe as a vocabulary check, not a coverage check - it greps for keywords, so "review expectations: mentioned" means a word matched, not that the topic is handled. Read the file before repeating any probe result to the maintainer.
3. Collect from the forge's own interface or API what the script cannot see: the funnel-baseline figures listed in the scorecard's report format, plus the current stock of unclaimed beginner-friendly issues and their age. Use a 90-day window for response times and four quarters for contributor counts - both windows are this skill's own defaults, not published standards.
4. Read the last ten pull requests from people who are not maintainers, oldest comment first. Note where each one stalled and what the first maintainer reply said, if there was one.
5. If your environment has persistent memory, load any stored scope statement, response target, or audience definition for this project rather than re-deriving it.
The script reports facts, not judgements. Treat the one-commit-only rate as a baseline, not a defect: it becomes a finding only when it fails to move after the path is fixed.
Score the current path with [./references/contributor-path-scorecard.md](./references/contributor-path-scorecard.md) and show the maintainer the result before proposing changes. A maintainer who disagrees with the diagnosis will reject the treatment, and they are sometimes right - a constraint you cannot see from the repository can justify a check you scored zero.
## Step 2 - Walk the path yourself
Follow the cold-run protocol in [./references/contributor-path-scorecard.md](./references/contributor-path-scorecard.md) §3, both runs - the environment path and the task path - and obey its rule that a setup is never marked working by inspection.
Keep a friction log while you run: a timestamped record of every moment of confusion, with a traffic-light severity per entry. Note, for each entry:
- what you expected
- what happened
- what you had to know that was not written down
Do not fix anything mid-run. Fixing hides the size of the problem.
## Step 3 - Fix the environment before the prose
Documentation describing a broken setup is worse than no documentation, so this step comes before any writing. Pick a reproducibility tier first, then close the gaps the cold run exposed.
Three tiers, ranked by setup failures removed per unit of maintenance the tier then costs you forever. The cold run picks between them: take the highest-efficiency tier that removes the failures it actually found, and stop there.
- efficiency: `bootstrap command > pinned toolchain > container definition`
- value (failures removed): `container definition > pinned toolchain > bootstrap command`
- effort: `container definition > pinned toolchain > bootstrap command`
1. **Bootstrap command** - one `make setup` or `./script/bootstrap` that installs dependencies, prepares fixtures, and ends by running the test suite. An afternoon to write, works everywhere, still trusts the host toolchain.
2. **Pinned toolchain** - a version file the host's tool manager reads, plus a committed lockfile. Removes most "works on my machine" reports for the cost of one file and the upgrades it then forces.
3. **Container definition** - a development-container definition that both a local editor and a cloud workspace can consume. Strongest reproducibility and highest maintenance: a standing job, and the tier that rots fastest when maintainers do not use it themselves.
- What this order starves: the container definition, the only tier that removes a whole class of environment failure. Promote it when the stack needs services or a painful toolchain (interview question 11) - there the cheaper tiers remove nothing, and an ordering is never a reason to ship a fix that does not work.
- Re-rank against what you know: a team already running containers in CI has paid that tier's effort, which moves it to the top of the efficiency line for that project alone.
Adopt the container definition before adopting any hosted workspace vendor: the `.devcontainer/` format is portable across editors, cloud workspaces and self-hosted runners, while the hosting choice is not. Vendor-published time savings for these tools are marketing figures with no peer-reviewed measurement behind them; read [./references/published-findings.md](./references/published-findings.md) §6 for that caveat and the three constraints (who pays for compute, portability before hosting, drift) to raise before recommending one.
Then close the gaps, in this order:
- Make every gate CI enforces runnable locally with one documented command. A contributor who cannot reproduce a red check locally is stuck by definition.
- Split the pipeline into a credential-free lane that always runs on fork pull requests and a privileged lane a maintainer triggers. Jobs needing secrets cannot run on a fork, and they show red to exactly the people who need reassurance. Where an approval gate holds fork runs entirely, say in the file who approves it and how fast.
- Turn on maintainer edits to contributor branches, and say in the file that you do it, so a stalled pull request can be finished rather than closed.
- State the merge style (squash, rebase, merge commit), because it changes how contributors structure their commits.
Re-run the cold run from clean after each fix. The step is done when nothing new is discovered.
## Step 4 - Stock the first-issue queue
A beginner label is a promise of mentoring, not a difficulty rating. Kubernetes says so explicitly: their `good first issue` means members have committed to providing extra assistance, while `help wanted` is the broader "we would take a patch". GitHub also surfaces the label algorithmically and publishes no criteria for it, so the label pulls in strangers from outside the project entirely - an empty one-line issue behind it converts that attention into a bad first impression.
1. Stop fixing easy bugs yourself; each one is a recruiting opportunity spent on twenty minutes of your own time. Kent C. Dodds, whose 2015 post created the `first-timers-only` convention, states the trade: "Could I have finished it quicker and moved on my way if I'd just done it myself? Of course. But that's not what it's all about as an open source contributor." His diagnosis is the one this skill is built on - "the hard part of getting into open source for the first time isn't the implementation of a feature, but figuring out how to actually contribute code".
2. Write each candidate issue with the seven parts: observed behaviour, expected behaviour, the file and its test, the skills or APIs required, a suggested approach or an explicit "design not settled - discuss first", the exact verification command, and a named mentor. One 74-participant study (Steinmacher et al., arXiv:2103.12653) found newcomers picked issues labelled with the _technical domain required_ over issues labelled by architecture area - the question they ask is "can I already do this?", not "is this easy?".
3. Size each issue at roughly one evening for someone who has never seen the codebase, setup included - this skill's own sizing default. A one-word typo fix teaches nothing and produces a contributor who never returns.
4. Reserve non-code entry points explicitly - documentation, tests, triage, translation, examples. They are the widest door and the first thing an all-code queue loses.
5. Publish the claiming convention and a stale-claim expiry, then apply it. A queue that looks full but is entirely claimed by absent people is worse than an empty one.
6. Keep a standing stock of at least three valid unclaimed issues - a self-set floor. Someone who finds zero does not come back later to check.
See [./references/first-issue-and-review-examples.md](./references/first-issue-and-review-examples.md) for a weak and a strong issue body side by side.
## Step 5 - Write the CONTRIBUTING file
Draft section by section against [./references/contributing-file-outline.md](./references/contributing-file-outline.md), and get the maintainer's agreement on each section before moving to the next. A file rewritten in one pass gets rejected in one pass.
Hold four rules while drafting:
- Write only what is now true. Every command in the file must be one you ran in step 2 or 3.
- Publish the response target you can actually hold, from interview question 4. A stated seven days that is met beats a stated 48 hours that is missed.
- Put the legal gate before the reader writes code, never at the gate itself. Where the project still has the choice, a sign-off line (`git commit -s`) costs a contributor nothing, while a signing workflow stops a typo fix - which is why the CNCF encourages projects to use a DCO "as it's easier to setup and use". The choice itself belongs to samber/developer-relations-skills@oss-license-strategy; only its placement in the file is yours.
- Write for the agent reading it too: state conventions literally and near the top, write the commands out rather than only the wrapper, and keep every mandatory step inside the file rather than behind a link. The outline's §6 reads GitHub's own repo-contribution skill as the spec these three rules come from.
Place the file where the forge surfaces it and keep exactly one copy (outline §1), and link the neighbouring files instead of absorbing them (§4).
Run the finished prose through your preferred humanizer skill. A contributing guide that reads as generated undermines the welcome it extends, and this audience spots it immediately.
## Step 6 - Design the review and recognition loop
1. **Acknowledge on a separate clock from reviewing** - the two-clock rule. A same-day "thanks, I have seen this, review by Thursday" preserves the relationship when the real review is a week out. Silence is the expensive failure, not slowness.
2. **Answer scope in the first comment.** Discovering a pull request is out of scope after three review rounds is the worst outcome in the funnel for both people.
3. **Review in a fixed order:** scope, then correctness and tests, then design with the reasoning attached, then style - and only the style the formatter missed. Anything a machine can fix must never appear as a human review comment.
4. **Label blocking versus optional** on every comment. An unlabelled mix reads as a wall of failures.
5. **Decline fast and kindly** when you must: thank them, name the scope rule, link where it was published, offer an alternative issue, close. A quick no beats a pull request rotting for six months.
6. **Credit at merge**: preserve the contributor as author, name them in the release notes, and record non-code contributions somewhere the commit graph cannot - docs, triage, and design work are otherwise invisible.
7. **Invite the second contribution explicitly**, with a named next issue. This is the moment a drive-by becomes a contributor, and it almost never happens on its own.
8. **Write down what happens when a pull request stalls**, from both sides, and offer to finish it yourself rather than letting a bot close it.
Review against the written scope rule and that fixed order, never against an impression of the person - it is the cheapest available control on reviewer bias. Terrell et al. (PeerJ CS 3:e111, 2017) analysed 3,064,667 pull requests and found that on _outside_ contributions - exactly the population this path serves - women's merge rate was 58% against men's 61% where gender was identifiable, while gender-neutral profiles scored highest of all. Gender was inferred and only 35.3% of users were linkable, so treat the direction as robust and the exact percentages as not; caveats in [./references/published-findings.md](./references/published-findings.md) §5.
Turn items 1-8 into a short written playbook the maintainers actually share, and mirror the response target into the CONTRIBUTING file so contributors and maintainers read the same number. Reply templates for each situation are in [./references/first-issue-and-review-examples.md](./references/first-issue-and-review-examples.md).
## Step 7 - Decide against the shortcuts before spending on them
Maintainers reach for a mentorship program, an onboarding event or a bot when the real problem is one of the six steps above. Each is a legitimate accelerator on a working path and a waste on a broken one, so make the call explicitly rather than by enthusiasm.
Rank them only after steps 3-6 hold: on a broken path every one scores zero whatever the ordering says. Effort means maintainer hours committed and how hard the thing is to stop once announced. Value means contributors who return.
- efficiency: `bot > structured program > onboarding event`
- value: `structured program > bot > onboarding event`
- effort: `structured program > onboarding event > bot`
- compliance cost: `structured program > onboarding event > bot`
- **A bot** may absorb mechanical work, never a human moment. Leads the efficiency line on its denominator alone - an hour to install, near-zero afterwards, and reversible in one commit. Keep the first reply, the decline and the stall check-in human (step 6), and treat any wait-state a bot or approval gate introduces as a step 3 gap to document.
- **A structured program** (Google Summer of Code, Outreachy, LFX Mentorship, MLH, Season of Docs) supplies the stipend and the cohort; you supply mentor hours - a standing job for a whole season, and the only item here you cannot abandon halfway without someone's summer attached to it. Host one only once steps 3 to 6 hold, because an under-mentored intern costs more than no intern. Do not promise it fixes retention: the two most-cited studies disagree, and the Mozilla analysis (Labuschagne & Holmes, MSR 2015) found contributors who started on a good-first-bug or mentored bug were _less_ likely to become long-term contributors. Figures and caveats are in [./references/published-findings.md](./references/published-findings.md) §3-4.
- **An onboarding event or sprint** teaches mechanics well and converts nobody on its own. Last on efficiency because it costs a week of preparation plus the follow-up and buys the least measured return of the three. Kubernetes ran the field's most resourced workshop and retired it because "running the session during the summit never led to any people who weren't already contributing to the project becoming dedicated contributors". Budget the follow-up - a named next issue, an assigned mentor, a second-contribution nudge - or skip the event.
- Delete **a reward with no quality gate** rather than ranking it last, and say you deleted it: it buys volume you cannot review, which is a cost, not a small benefit. Hacktoberfest's 2020 spam wave forced opt-in repositories, a longer grace period and the removal of the T-shirt entirely.
- What this order starves: the structured program - highest value of the three, and the only one that brings people who were never going to find the project alone. Promote it when a second reviewer exists (interview question 12) and the maintainer hours in question 4 clear a mentor's weekly commitment for a full season.
- Read the compliance line as the obligations each signs you up to:
- a structured program: a third party's participation agreement, mentor commitments, stipend administration, and its code of conduct for a season
- an event: a code of conduct and a venue
- a bot: neither
The deleted reward carries published prize rules - what Hacktoberfest had to rewrite mid-event.
- Treat this ordering as a default, not a law: it shifts with the project and with who maintains it. Re-rank against what you know - an employer already funding mentor time, a co-maintainer who has run a cohort, an existing event to attach a sprint to - each moves an item up before the default applies.
## Step 8 - Re-score, then hold the target
Re-run the scorecard and iterate until it clears its threshold - all four blocking checks, plus 12 of 16 scored points. That mark is this skill's own baseline, not a published one; §4 of the scorecard has the wording to give a maintainer who asks where it comes from.
Then hold it, because the path decays - a new dependency breaks the bootstrap, the beginner queue empties, the response target slips. Re-run the audit script and one cold run every quarter - this skill's own cadence - and after any change to the build or the test command. Where your environment supports scheduled routines, install that re-check as a recurring task; where it does not, leave the maintainer a dated calendar reminder and a one-line command to re-run.
If your environment has persistent memory, store the agreed scope statement, the published response target, the beginner-issue definition, and the score with its date, so the next run measures a delta instead of starting over.
## What to track afterwards
At low volume these signals are anecdotes with dates attached, not a dashboard. Four external pull requests a quarter cannot produce a trend, and a conference talk or a front-page mention moves every number below more than a documentation change does. Record the date you shipped each change, annotate the confounders, and only then read deltas.
Track the scorecard's funnel baseline, reading each number this way:
- **New external contributors per quarter** - the headline number, and the noisiest.
- **Second-contribution rate within 90 days** - the retention number the whole path exists to move; the window is this skill's own default.
- **Median time to first human response**, bots excluded, against the 48-hour reference point.
- **External first-pull-request merge rate and median time to merge**, tracked separately from maintainers' own pull requests, which are always faster and hide the number that matters.
- **Contributor absence factor** - it should rise slowly; it is the only one of these that measures whether the project got less fragile.
- **Setup support load** - issues and chat messages that are really "I could not build it". A fixed path drives this to near zero, and it is the fastest-visible win.
## Common failure modes
- **Labelling old bugs as beginner-friendly.** Small for someone who knows the codebase is not small for a stranger. If it has no location, no verification command, and no mentor, it is not a first issue.
- **Optimizing recruitment while review is the bottleneck.** More contributors arriving at an unstaffed review queue produces more abandoned pull requests and more resentment on both sides. Fix step 6 before promoting the project.
- **Quoting an outcome number as if it transfers.** "80% of interns keep contributing" is a self-reported figure from one program's alum survey with a 37% response rate. Measure the project's own funnel, time to first response, second-contribution rate, instead of importing someone else's result.
- **Copying a large project's process.** A ten-person project running Kubernetes' ladder, sponsors and rota spends its whole budget on process for contributors it does not have yet. Take the shape, not the scale.
## Reference
- [./references/contributor-path-scorecard.md](./references/contributor-path-scorecard.md) - rubric, cold-run protocol, pass threshold, and report format
- [./references/contributing-file-outline.md](./references/contributing-file-outline.md) - section-by-section outline, volunteer-versus-corporate split, agent legibility, compact skeleton
- [./references/first-issue-and-review-examples.md](./references/first-issue-and-review-examples.md) - weak and strong issue bodies, first reply, review comments, decline, merge message, stall check-in
- [./references/published-findings.md](./references/published-findings.md) - sources and caveats for every figure cited, plus self-set baselines
- [./scripts/contributor-path-audit.sh](./scripts/contributor-path-audit.sh) - mechanical facts the scorecard depends on
- samber/developer-relations-skills@readme-optimization - repository landing page
- samber/developer-relations-skills@developer-quickstart-guide - user's first success with product (not contributor path)
- samber/developer-relations-skills@oss-governance - decision rights and maintainer selection
- samber/developer-relations-skills@developer-community-moderation - code of conduct and enforcement
- samber/developer-relations-skills@oss-launch - attracting an audience
- samber/developer-relations-skills@developer-journey-map - the stage this contributor path feeds