InnerSource Contribution Contract
also called Contribution Contract, InnerSource Maintainer Contract
The published statement of what a shared internal component accepts what it refuses and how fast it will answer - which makes a maintainer's "no" fast and survivable instead of turning openness into an unbounded support obligation.
A team of five maintains a library used by 60 other teams and owns two products of its own. Two contributions arrive in one week: one adds a caching layer with its own configuration surface, the other a second serialisation format. Both contributing teams are blocked and both say innersource means they can contribute.
Every option available is bad, which is the symptom of a missing contract. Merge both and the library becomes the union of every caller's local needs with the maintainer supporting all of it. Refuse with no reason and credibility goes. Say nothing for three weeks — the most common outcome — and 60 teams learn not to bother.
A contribution contract is the small written artefact that makes refusal cheap and fast: what the component is for, what changes are accepted, what will be refused, and what response a contributor can expect.
Why it matters
Openness is not the constraint in innersource; review and long-run support capacity is. Reviewing a first contribution to unfamiliar code typically costs the maintainer one to three times what writing it would have cost, and that is the cheap part. The expensive part is permanent: every future change must keep the contribution working for every caller.
Without the contract that cost is invisible and unfunded, so maintainers ration it by being slow. The programme reads the silence as cultural reluctance and responds with a contribution target, which makes things worse. The health metric is time to first response, not contributions merged, because a 2-day response with a clear no produces more future contributions than a 3-week silence ending in a merge.
Implementation patterns
- A CONTRIBUTING file with four parts: what the component is for and not for; accepted categories (bug fixes, adapters at existing seams, tests, documentation); refused categories (configuration surface for a single caller, features with no second consumer, anything whose failure would be debugged by callers); and a response commitment such as first response in 2 business days and a decision within 10.
- Seam-first policy. Accept the extension point rather than the feature: a pluggable codec boundary, with the format owned in the contributor's module. The maintainer takes the seam and the contributor keeps the feature, converting a refusal into a smaller accepted change.
- A named trusted committer, so review is somebody's job rather than an interruption to everybody's, and funded review capacity on the order of 10 to 20% of the owning team's time, budgeted and reported as platform cost.
Industry example
The mechanics are borrowed from open source, where the same economics produced CONTRIBUTING files and maintainer triage rotations. The InnerSource Commons publishes a public pattern catalogue at patterns.innersourcecommons.org covering the structural roles including Trusted Committer, and its recurring theme is that the host team's capacity and responsiveness are the scarce resources, not contributors' goodwill.
The instructive internal case is the inverse: an organisation that opened every repository and set a company goal for cross-team contributions, with no refusal criteria and no response commitment. Openness was total, the contract absent, and nothing moved.
Failure scenarios
- The silent queue. Contributions age past relevance; the contributing team ships a local fork, and the component acquires hidden competitors in production.
- The union library. Everything merged to be a good citizen, so the component gains a configuration surface per caller and the maintainer owns behaviour they would never have built.
- The contract as a wall. Refusal criteria so broad nothing qualifies, which is no innersource with more paperwork. A quarter with zero accepted contributions means it needs re-reading.
Trade-offs
| Choose | Gains | Pays |
|---|---|---|
| Published contract with a response SLA | Fast honest answers and a maintainable component | Writing it and being held to the response times |
| Open with no contract | Looks maximally collaborative | Unbounded review queue and a component shaped by whoever pushed hardest |
| Closed with a request queue | Predictable roadmap and one owner | Blocked callers and the three-week wait innersource exists to remove |
When not to use it
For a component with a short remaining life — retired next quarter, or absorbed into a platform — take the contributions that unblock people and accept the divergence. The contract earns its cost where the component has years of life and many callers.
Interview question
Q: Your team owns a library used by 60 teams and you have just received two pull requests you do not want. Both contributors are blocked and both cite the company's innersource policy. How do you handle it this week, and what do you change so the week does not repeat?
What a strong answer covers: answering in public within two days with reasons; offering a seam instead of the feature; recognising that long-run support cost rather than review effort makes the refusal correct; and escalating the resourcing question as the structural issue.
Quick check
Quiz: What is the binding constraint on innersource, and which metric reflects it? Maintainer review and long-run support capacity; time to first response, not contributions merged.
Flashcard: How do you refuse a contribution and keep the contributor? — Answer in two days with the reason, then offer the extension point rather than the feature: you take the seam and they own the module.