Repository navigation
Contributing
How work gets proposed, built, and shipped — for me and for anyone else touching this public repo. See Vision for why; this page is about process, not direction.
A mostly-automated delivery loop where owners role is approving tickets and approving PRs, not writing code day to day: a draft idea gets refined, estimated and implemented by set of abi83/interns agents and I do the final check and merge, focusing on product vision and strategy. Dev and prod are separate environments; prod only moves forward once new release is ready. Deterministic quality gates (automated tests, linting, type-checking, dependencies audit) help ensure quality, and the agents are held to the same bar as anyone else.
Anyone can open an issue or a PR here, but without owner direct approval issue cannot be processed, PR cannot be closed.
Issue tracking uses the refine → estimate → code → review flow from abi83/interns — labels, state machine, fix-round loop, per-agent tuning in .github/interns.yml all come from there directly.
What's specific to Prepify is the trust boundary: issues I write enter the interns pipeline automatically; issues opened by anyone else sit untouched until I've looked at them and brought them in myself (see above). Merge is always mine, regardless of who or what opened the PR.
Run metrics: abi83.github.io/prepify/interns-metrics
Process rules live here; how to write the code itself is binding on separate pages:
- Contributing-Nextjs-Guidelines (rendering/data flow, file & naming conventions, types, control flow)
- Contributing-UI-Guidelines (styling and UI components).
Read both before opening a coding-task PR.
Issue types, labels, and templates follow abi83/interns conventions. Issue body follows its type:* template — don't pad it past what the template asks for.
Epic structure follows abi83/interns conventions. Only I create epics (or an agent when I explicitly ask). Every issue except bugs is a sub-issue of an epic — a coding-task or spike without a parent is invalid. Bugs can stand alone.
Two distinct native GitHub relations are in play — always use these; a plain-text #NN reference can be used as an additional (in-context) link, but not as a replacement:
| Relation | Tracks | How to set |
|---|---|---|
| Sub-issue ("Parent issue") | Epic membership | Attach the issue as a sub-issue of the epic |
| "Blocked by" | Execution order — what can't start before what | Web UI, or gh api graphql with the addBlockedBy mutation (issueId + blockingIssueId, both GraphQL node IDs) |
State what was actually done or found, and the resulting status, in a comment when closing an issue that didn't close via a normal PR merge — investigated and turned out not reproducible, superseded, decided against, etc. Don't close those silently. If the work produced follow-ups, link them by number — GitHub's sub-issue relation is parent/child only, so a lateral "this investigation led to that follow-up" link stays a plain #NN reference in text.
main is protected — no direct pushes, every change lands via a branch and a PR, no exceptions. PRs are squash-merged, so the PR title becomes the commit on main — write it as a Conventional Commit (feat:, fix:, refactor:, etc.). release-please reads that commit history on main to derive version bumps and the changelog; a non-conventional title is an invisible, unlabeled change to it.
Keep them short and direct — the same conciseness bar as code and docs. Rationale, background, and root-cause analysis live on the issue; the PR says what changed and what to check.
PR body — three sections, nothing else:
- What changed — bullets, the diff itself
- Before merging — checklist of anything the PR depends on: a new Actions variable or secret, a migration to run, a setting to flip. Create it as part of the work and tick the box.
- After merging — checklist of what to verify once it's live
A Notes section is for a genuine exception (a known follow-up needed, a deliberate deviation), not a routine part of every PR.
- Something out of scope spotted mid-work — dead code, a stale doc, a second bug — gets offered as a follow-up PR or a ticket in Notes, not folded into the current branch and not left as an inline #fixme comment.
- A reviewer comment that exposes a real gap (undocumented config, a missing test) gets fixed on the branch, not answered with a reply alone.
| PR size (lines changed) | Ticket required | Native "Development" link required |
|---|---|---|
| ≤10 | No — straight to a fix: PR |
No |
| ≤500 | Yes | Yes |
≤1000 — ticket labeled size:XL
|
Yes | Yes |
The reviewer pass and the owner merge always apply, regardless of size — only the ticket and linking requirements scale with it.
When a Development link is required, it covers:
- the issue the PR implements
- a followup issue the PR addresses
- a bug ticket for a regression the PR fixes
If the PR fixes a bug that a prior PR introduced, also add a plain #NN reference to that prior PR — there's no native PR-to-PR link.
- Every Acceptance Criteria checkbox is checked
- Tests written for the change — placeholder until a real testing strategy exists (#78); once it does, this means whatever that strategy calls for
- All automated checks green (build/test/lint in CI — more of these land as #78 progresses)
- PR merged to main
- Wiki updated if the change affects any documented behavior
- For coding-task/bug: the change is verified actually working, not just green in isolation
- For spikes: the decision and its Deliverable are written down somewhere durable (wiki/ADR), not just decided in someone's head
The goal: whichever agent implements a ticket does its best to exercise the real change itself, rather than treating green tests/type-checks as proof the feature itself works:
- UI — drive a real browser: start the dev server, click through the actual flow, check console/network
- Backend — make real API calls
- Infra — run real
terraform plan/state showorgcloudcalls - Migrations — actually run it against dev and check the resulting schema
Deploying to dev first (not just running locally) is often the most realistic way to verify, especially for anything infra- or environment-dependent.
This is a direction to grow into, not a hard gate yet — the tooling to do this well (agents with browser/API/deploy access on every ticket) isn't fully wired up. Until it is: do as much of the above as the available tooling allows, and say explicitly what wasn't verified and why, rather than silently skipping it or claiming full verification that didn't happen.