You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Maintainer-time is the bottleneck. Today's friction points: hand-merging master into every open PR, manual release notes, unacknowledged issues, Claude review acting as a blocking oracle, and no changeset discipline. This issue scopes a phased rollout so each piece lands independently and delivers value on its own.
Invariant (target state)
Maintainer's active work reduces to three things:
Triage decisions on accepted issues
Yes/no on PR changesets (content review, not mechanical merging)
Promoting canary → stable (a label flip, not a publish ceremony)
Foundation: protect the branch, standardize contributions, make issue reports actionable.
Branch protection on master: required typecheck + lint + unit tests + example-app build; dismiss stale approvals on push; enforce linear history; add CODEOWNERS on src/
Conventional Commits PR-title linter + squash-merge only policy — every merge produces a single, parseable commit
PR template with required sections: repro steps / before / after / changeset entry / breaking-change flag
Issue forms with required fields: library version, React Native version, platform (iOS/Android/both), Expo or bare workflow, Reanimated version, Snack or repro link
Auto-label from issue form metadata + PR title prefix (e.g., fix: → bug, feat: → enhancement)
Phase 2 — Releases run themselves (week)
Goal: merging a PR is the only manual step; everything downstream is automated.
Adopt changesets (or release-please) — every PR must include a .changeset/*.md entry; missing changeset = red CI check
Version Packages PR accumulates unreleased changes; merging it triggers: version bump → npm publish → git tag → GitHub Release with auto-generated notes
Continuous prereleases: every merge to master publishes x.y.z-next.N under the next npm dist-tag
Canary per-PR: publish 0.0.0-pr-<n>-<sha> on PR CI so reviewers can yarn add the exact change for drop-in testing
Stable release = label promotion on the Version Packages PR (no manual npm publish invocations)
SUPPORT.md: declared support window — latest minor + one minor back
DEPRECATED.md: breaking changes require a one-minor-release deprecation warning before removal
Phase 3 — PR flow runs itself (week)
Goal: eliminate merge toil and review bottlenecks.
GitHub merge queue enabled — queue-rebases safely, runs checks against the merge result, kills the "merge master into every PR" toil
automerge label → auto-merge when CI is green + required approvals met
Renovate or Dependabot with auto-merge on patch/minor bumps; major version bumps require human review
Review SLA bot: 5 days of silence → ping CODEOWNERS; 10 days → @-mention the PR submitter asking if still relevant
AI reviewers (Claude, Cursor, CodeRabbit) as advisory (non-blocking) checks — deterministic CI gates control merge eligibility, AI review informs but never blocks
Draft vs. ready-for-review enforced: draft PRs skip CI, reviewer assignment, and SLA timers
Phase 4 — Issue flow runs itself
Intake
Issue Forms (.github/ISSUE_TEMPLATE/*.yml) — bug, feature, question. Required fields: lib version, RN version, platform, Expo/bare, Reanimated version, Snack/repro link. Free-text only for "what happened"
Blank issues disabled
Auto-label on open from form fields: platform:ios|android, rn:<version>, area:zoom|pan|pinch|static-pin, reanimated:yes|no
Triage
needs-triage auto-applied on open; removed when any action label lands
Why
Maintainer-time is the bottleneck. Today's friction points: hand-merging
masterinto every open PR, manual release notes, unacknowledged issues, Claude review acting as a blocking oracle, and no changeset discipline. This issue scopes a phased rollout so each piece lands independently and delivers value on its own.Invariant (target state)
Maintainer's active work reduces to three things:
Everything else — versioning, release notes, npm publishes, branch updates, dependency PRs, stale issue cleanup — runs automatically.
Phase 1 — Stop the bleeding (days)
Foundation: protect the branch, standardize contributions, make issue reports actionable.
master: required typecheck + lint + unit tests + example-app build; dismiss stale approvals on push; enforce linear history; addCODEOWNERSonsrc/fix:→bug,feat:→enhancement)Phase 2 — Releases run themselves (week)
Goal: merging a PR is the only manual step; everything downstream is automated.
changesets(orrelease-please) — every PR must include a.changeset/*.mdentry; missing changeset = red CI checkVersion PackagesPR accumulates unreleased changes; merging it triggers: version bump → npm publish → git tag → GitHub Release with auto-generated notesmasterpublishesx.y.z-next.Nunder thenextnpm dist-tag0.0.0-pr-<n>-<sha>on PR CI so reviewers canyarn addthe exact change for drop-in testingnpm publishinvocations)SUPPORT.md: declared support window — latest minor + one minor backDEPRECATED.md: breaking changes require a one-minor-release deprecation warning before removalPhase 3 — PR flow runs itself (week)
Goal: eliminate merge toil and review bottlenecks.
automergelabel → auto-merge when CI is green + required approvals metCODEOWNERS; 10 days → @-mention the PR submitter asking if still relevantPhase 4 — Issue flow runs itself
Intake
.github/ISSUE_TEMPLATE/*.yml) — bug, feature, question. Required fields: lib version, RN version, platform, Expo/bare, Reanimated version, Snack/repro link. Free-text only for "what happened"platform:ios|android,rn:<version>,area:zoom|pan|pinch|static-pin,reanimated:yes|noTriage
needs-triageauto-applied on open; removed when any action label landsneeds-triage → needs-repro → accepted → in-progress → shipped/duplicate #Nneeds-repro/accepted(+size) /wontfix/duplicateRepro enforcement
needs-reproauto-applied if repro-link field is empty or non-URLneeds-repro→ comment at 7d, close at 14d;acceptedexemptcant-reproworkflow: boilerplate ask for minimal Snack, 7d closeCategorization
size:XS/S/M/L/XL) from linked PR diff / discussion length/severity <level>slash command from CODEOWNERS appliesseverity:*Communication
accepted— sized M, milestone v2.1")Closes #N/Fixes #Non non-chore PRs = red checkContributor funnel
good-first-issue+help-wantedsurfaced in README (badge + live count)CONTRIBUTING.md+ DCO/CLA checktype:questionissues auto-converted (or redirected) to GitHub DiscussionsAnti-patterns (explicit non-goals)
Metrics surfaced
open → accepted/closedtime (triage SLA)acceptedcount (backlog rot)Implementation
actions/stale,actions/labeler,dessant/label-actions,peter-evans/create-or-update-comment,actions/github-script, Projects v2 automationTarget maintainer session
needs-triagecolumnPhase 5 — Codebase enables the above (ongoing, tracked separately)
These are larger efforts that will each get their own tracking issue, linked back here:
@paramtypes, completeReactNativeZoomableViewPropsinterface)Out of scope (for this issue)
Order of operations
1 → 2 → 3 → 4 in series — each phase unblocks the next. Phase 5 runs in parallel starting whenever bandwidth allows.