Running a contribution area
For maintainers: enabling External Contributions, reading the Contributions tab, reviewing revisions, required checks, contribution permissions, blocking, and the difference between accepting and integrating.
A repository's contribution area is where people who are not members of it offer work. This guide is for the people who run one: how to open it, how to read what arrives, and what each moderation decision actually does.
The contributor's side of the same feature is documented separately, at Contributing to someone else's repository.
Enabling External Contributions
External Contributions are off by default, whatever the repository's visibility. Visibility and contributions are two independent settings: making a repository public lets people read it, and nothing more. Nobody can offer work to it until you turn contributions on.
The switch is on the repository's Settings → Contributions section, and it needs maintainer access. Turning it on gives anyone who joins their own contribution workspace on this repository, derived from the repository's accepted state and pinned to the version it was derived from. It grants no access to the repository's own branches: a contributor's authorization carries write access narrowed to their single workspace, and the server refuses anything outside it rather than trusting the client to stay inside.
The same section links to the two pages you will use afterwards: the contribution requests themselves, and the contributors, blocks and required-check settings.
The Contributions tab
The repository gains a Contributions tab listing every request. Each row is evidence a maintainer can act on, and nothing more:
- state, title, author, and how many revisions there have been;
- what changed — files changed, lines added and removed;
- what the contributor declared — the change types, the impacts they flagged, and their testing statement;
- what the platform observed — how many checks passed, failed, warned or are pending, and how many required checks are still unsatisfied;
- the review posture, and whether the base has drifted since the revision was written.
Rinko Hub supplies counts and leaves the judgement to you. There is no reputation number, no tier and no trust label anywhere in this feature — a contributor's history is available as plain counts (created, accepted, rejected, withdrawn, closed, revisions, checks passed and failed) and never as a verdict the platform has already reached on your behalf.
Reviewing, one revision at a time
A Contribution Request holds a numbered sequence of immutable revisions. A revision is a content-addressed version that cannot be rewritten after you have read it, so what you reviewed stays exactly what you reviewed.
A review is therefore bound to the revision it read. Three verdicts exist — comment, approve and request changes — and a review may only be submitted against the current revision; submitting one against a superseded revision is refused rather than silently applied to newer work. When the contributor submits a new revision the request returns to open, and earlier verdicts are marked as being about an earlier revision. Approvals do not carry forward, because the approval was a statement about something specific.
Each revision records two bases, both captured at submission and neither inferred afterwards: what the contributor's workspace was pinned to, and what the target workspace had selected when they submitted. That is what makes base drift a comparison rather than a guess.
Checks and required checks
A check is the platform's own observation about one revision, written by a check provider. It is never the same kind of statement as the contributor's declaration, and the two are never merged: a contributor saying their tests passed does not produce a passing check.
A check run carries a status — queued, running, passed, warning, failed, skipped or error. error is deliberately distinct from failed: a broken check runner is not a broken contribution, and collapsing the two would report one as the other.
On the Contributors, blocks and required checks page you decide how much authority the repository gives each check type. Three levels exist:
| Level | Effect |
|---|---|
| informational | Shown, and nothing more. This is what an unconfigured check run is. |
| recommended | Shown as something the repository asks for. Does not block acceptance. |
| required | Blocks acceptance until it has passed for the revision being accepted. |
A required rule is satisfied only by a passing run against the exact revision you are accepting. A pass recorded against an earlier revision counts as pending — the evidence has to be about the thing being accepted. A check run that matches no rule is informational, so a provider can never promote its own result.
Accepting past an unsatisfied required check is possible, and it requires a written reason. It is recorded as its own event with the actor, the reason and the checks that were pending, so the audit trail says a decision was made rather than implying evidence existed. Writing a passing check by hand would leave a trail that lies, which is why the ability to author check results by hand is narrower than the ability to accept.
Who may do what
Seven repository permissions govern the contribution area. They are checked on every request, on the server; a control you cannot see is a control the server would also refuse.
| Permission | What it allows |
|---|---|
contributions_read | Read the contribution queue. Tied to being able to view the repository, so on a public repository anyone may read it — the same bar as reading the code. |
contributions_review | Comment, approve, request changes. |
contributions_manage | Change the settings, close or reject, manage the area. |
contributions_accept | Accept an approved contribution, including the audited override. |
contributors_manage | See the contributor list, revoke a registration. |
contributors_block | Block and unblock accounts, and read the private notes on blocks. |
contribution_checks_manage | Write check results by hand, and set required-check rules. |
Roles map onto them as follows:
| Role | Holds |
|---|---|
| Owner, admin | All seven. |
| Maintainer | All except contribution_checks_manage, which is admin-only for the reason
above. |
| Contributor (repository member) | contributions_read and contributions_review. |
| Anyone who can view the repository | contributions_read. |
Reviewing is deliberately wider than accepting: a repository can open review to its own contributors without also handing them the power to decide what it accepts. A request's author can always read, revise and withdraw their own request, and can never approve it.
Blocking and unblocking
Blocking is repository-scoped. It says this account may not offer work here, and says nothing about the account anywhere else on Rinko Hub. It needs maintainer access — moderating who may propose work to a repository is ordinary repository work, and routing it through administration would leave a repository without an admin unmoderated.
A block does four things, and no more:
- records the block, with who made it and when;
- revokes the contributor's registration, with the reason recorded as a block;
- withdraws their narrowed write access immediately rather than at expiry, so an authorization they already hold stops being honoured;
- refuses their further mutations on this repository.
Nothing is destroyed. Their workspace is repository state and is not deleted. Requests they already submitted stay in whatever state they were in, and remain readable and reviewable. What stops is their ability to submit or revise here.
A block may carry a private note. The note is visible only to callers holding contributors_block. It never reaches the contributor, never appears in the event
feed, and is never part of the data an applet can read.
The contributor is told one sentence, identical to the one every other ineligible account sees:
Contributions are not available for your account on this repository.
It deliberately says nothing about why. A message that distinguished a block from any other ineligibility would be an oracle for your moderation decision, readable by anyone willing to try.
Unblocking lifts the block and nothing else. The registration stays revoked, and the contributor registers again if they want to — which reactivates the same workspace with the base it already had. Silently reactivating would hand back write access the person never asked for.
Revoking a registration is the milder action, available with contributors_manage: it ends the registration without recording a block. The same
preservation rule applies — the workspace and everything submitted stay where they are.
Turning contributions off
Disabling stops new registrations, new requests, new revisions and new narrowed write access. It deletes nothing. Every existing row stays exactly as it was.
A second setting, Existing work stays reviewable, decides what happens to the requests already open: whether maintainers may still review, accept and integrate them, or whether the area goes quiet entirely until contributions are turned back on. Both choices keep the records.
Accept is not integrate
These are two decisions, and Rinko Hub keeps them two decisions.
Accepting requires an approved request and every required check passing for the current revision, unless you record an override with a reason. It makes the exact reviewed version a candidate of the target workspace — a version competing to become its state, sitting beside whatever else competes. There is deliberately no "accept anyway" path that skips approval: an accepted contribution with no approval on record would make the audit trail claim a review happened that did not.
Integrating is the separate act that makes it the state. It needs both contributions_accept and the repository's merge permission, and it comes in two
kinds: select, when the accepted version can simply become the selected version, and merge, when the base has drifted and the two lines must be reconciled. Both guard
against the workspace moving underneath you: if the selection changed since you read it, the
change is refused rather than applied to state you never saw. A conflicting merge is an outcome,
not an error — the request stays accepted and unintegrated so the conflict can be resolved and
the integration retried.
The request records both facts separately, so it can never claim the repository contains something it does not. Every step along the way — the settings change, the registration, the block, each revision, each review, each check, the acceptance, the override, the integration — is an append-only event carrying who did it and when.