Instructions for

In the forking workflow contributors don't push to the canonical repository at all. They fork it, work on their own copy, and open a pull request from the fork. The maintainer's job is a review gate: triage what comes in, run it through checks, and merge only what clears sign-off. It's the model most open-source projects run.

Shelbi models the maintainer's side. Shelbi never fetches from a fork, so you bring each contribution into your own checkout as a local branch and name it in the issue's branch: field. The workflow is mostly about the gate: a handoff sign-off status that's owner: user so nothing reaches main without a human accepting it.

The board

opensource-lib
Orchestrator⌘O
Issues⌘I
Changelog⌘L
Workspaces
alphaIdle
bravoReviewer⌘1
Zen mode off
Filter:WorkflowsWorkspacesboard 2sSearchNew issue
INCOMING3
PR #402: add retry backoff
PR #404: fix typo in docs
PR #405: Windows path bug
TRIAGE1
PR #398: new export format
IN REVIEW1
PR #401: perf: cache regex
you/pr-401
SIGN-OFF1
PR #399: async file API
you/pr-399
MERGED1
PR #395: bump deps
DECLINED0
h/l column k/j card ↵ open ⇧h/⇧l move ⇧k/⇧j reorder drag to move or reorder s start a assign e edit E editor n new

A fork PR lands in Incoming, the orchestrator triages it into scope, the reviewer agent runs it through checks in In Review, and it waits in Sign-off for a maintainer to accept before it's Merged.

The statuses

The forking flow relabels the whole board. Do it by renaming the shipped statuses in the project's status catalog (workflows/statuses.yaml) rather than replacing their ids. The shipped task and subtask workflows reference these six ids, and a missing one stops them from loading (and the whole project too, while task is its default_workflow). The id in-progress also matters on its own: Shelbi only hands finished work forward automatically from a status with that id.

# workflows/statuses.yaml — the shipped ids, relabeled for the forking flow.
statuses:
  - { id: backlog,     name: Incoming,  category: backlog }
  - { id: todo,        name: Triage,    category: ready }
  - { id: in-progress, name: In Review, category: active }
  - { id: review,      name: Sign-off,  category: handoff }
  - { id: done,        name: Merged,    category: done }
  - { id: canceled,    name: Declined,  category: archived }

The workflow

# workflows/contribution.yaml — reference-only; identity lives in statuses.yaml
name: contribution
description: Forking flow — review gate for pull requests from forks.
 
git:
  base_branch: main
 
statuses:
  - { id: backlog,     owner: user }                        # Incoming
  - { id: todo,        owner: agent, agent: orchestrator }  # Triage
  - { id: in-progress, owner: agent, agent: reviewer }      # In Review
  - { id: review,      owner: user }                        # Sign-off
  - { id: done,        owner: user }                        # Merged
  - { id: canceled,    owner: user }                        # Declined
 
initial_status: backlog
 
transitions:
  - { from: in-progress, to: review, actions: [] }   # no PR to open: the contributor already did

Set default_workflow: contribution in project.yaml so new issues use it (or put workflow: contribution in each issue's frontmatter).

The transitions: block is there to switch git side-effects off. A workflow with no transitions: block at all gets the legacy hand-off, which opens a PR. With the block, every edge that isn't listed with actions is a pure status move. Git work on GitHub stays yours:

  • No open_pr. The contributor already opened the PR from their fork. The issue just tracks it.
  • No merge or close_pr. Shelbi looks a PR up by the issue's branch name (gh pr list --head pr-401), which doesn't find the contributor's PR: its head is a branch on their fork. Merge or close the contributor's PR on GitHub, then move the card to Merged or Declined. With no merge edge, Zen Mode never merges a contribution either.
  • No delete_branch. The fork keeps its branch whether the PR merges or is declined.

To bring a PR in, fetch its head into the checkout Shelbi manages and point the issue at that branch:

git fetch origin pull/401/head:pr-401
---
id: pr-401
title: "PR #401: perf: cache regex"
branch: pr-401
---

If the branch doesn't exist locally when the issue is dispatched, Shelbi cuts a fresh, empty branch of that name off main, and the reviewer has nothing to review. When the reviewer hands off, Shelbi rebases pr-401 onto main and pushes it to origin under the same name, as it does for every task branch, so the contribution also shows up as a branch in your repo.

The In Review status names an agent: reviewer role, an agent you author to run the untrusted contribution through the project's checks and summarize risk before a human ever looks. Create it first with shelbi agent new reviewer: the workflow won't load until the agent exists. Or point the status at a shipped reviewer preset instead, security or adversarial. Because it runs in in-progress, the reviewer gets the same hand-off instructions as a developer: it writes the ready marker when it's done, and Shelbi moves the card to Sign-off. The Sign-off status stays owner: user: the gate is the whole point.

Orchestrator adjustments

The review gate needs the orchestrator to treat incoming forks as untrusted and never to auto-accept. Encode a triage rule and a hard stop at sign-off:

## Routing rules — forking
 
- **Incoming fork PRs** are untrusted. Never dispatch a contribution to a
  workspace that holds credentials or can reach production. Route `Triage`
  cards only to sandboxed hub workspaces.
- In `Triage`, decline anything out of scope (wrong direction, duplicate,
  no linked issue) into `Declined` with a one-line reason. Promote the
  rest to `InReview` for the `reviewer` agent.
 
## Zen Mode — forking
 
The `SignOff → Merged` edge is `owner: user` and must stay a human
decision. Do **not** auto-merge contributions even when checks are green:
report "`<PR>` passed review and is ready to sign off" and wait. A green
check is necessary but not sufficient for merging someone else's code.

That last rule is the difference between forking and trunk-based: trunk-based leans into auto-merge for your own green work; forking deliberately keeps a human at the gate for code that arrived from outside.

See also

  • Agents — how to author the reviewer role the InReview status dispatches to.
  • Workflows: the branch: task field: pointing an issue at an existing local branch instead of cutting one.
  • Trunk-based — the opposite end of the auto-merge spectrum, for work you trust.