What this page is about
This page is about how a one person side project stayed organized enough to actually ship, without turning "process" into its own second job, and without losing momentum to other commitments.
The setup
Everything lives in GitHub: Issues, a single Project board, and Milestones. No separate tool, no synced-but-not-quite-duplicate tracker somewhere else. A simple solution for a simple team and project: low complexity, low setup, low friction.
If it isn't in the issue tracker, it isn't real work yet.
That rule alone prevented the usual side-project failure mode, where half the todo list lives in your head and quietly falls off the moment things get busy.
The project board itself is intentionally thin: status, linked PRs, parent issue and sub-issue links (used sparingly, only for genuinely related work), start date, and target date. That's enough structure to answer "what's next" and "is this slipping" at a glance, without turning the board itself into a chore that gets skipped after a few days.
Issue conventions
Every issue title carries a tag: [Feat], [Fix], [Design], [Chore], or [Documentation]. It's a small thing, but it means scanning the issue list tells you the shape of the backlog before reading a single description: how much is new work, how much is cleanup, how much is chasing something broken. Labels (bug, enhancement, design, documentation) back this up for filtering and reporting.
The rule that mattered more than any label: every issue closes via a linked pull request. No closing an issue by hand and hoping the code shows up later. This keeps the issue tracker and the actual state of the code from drifting apart, which is the easiest thing to let slip on a project with no one else reviewing your work.
Every pull request also needs some kind of plan before it merges to main, even if that plan is just "run a full meeting start to finish and confirm nothing broke." Fast and functional is enough at this scale.
Epics, without the overhead of "epics"
Bigger efforts get tracked as a parent issue with a checklist of child issues, rather than a separate epic-tracking system. The visual overhaul is a clean example. One parent issue laid out the phases:
- Formalize the design tokens
- Port each of the four main screens to the new visual direction, one child issue per screen
Each child issue closed independently through its own PR as that piece landed.
The one gap worth naming: checkboxes on a parent issue don't auto-sync with the linked children's closed state. GitHub doesn't do that, so the checklist can say 80% done while the real state is either fully finished or barely started, depending on which way someone forgot to update it. The fix wasn't tooling, it was a standing habit: touch the parent checklist the same time you close the child.
Design work gets an extra gate
For anything tagged [Design], there's a specific rule: don't start implementing until there's an approved mockup attached to the issue, ideally an interactive artifact plus a written spec of exactly what's covered. If that approval isn't there, the answer is to stop and ask rather than guess at visual direction.
This rule exists because it got violated once. Time got burned building the wrong thing off a mental image of "this could work like X." The result was hours of SwiftUI tweaking on something that felt wrong the moment anyone actually looked at it and started clicking through. It was cheaper to write the rule down than to relearn the lesson.
Milestones as a pacing device, not a deadline hammer
Work got grouped into named milestones ("MVP," "v1.1 Polish & Fixes," "v1.2 AI & Speakers," "v1.3 Recording & Storage," plus a "Public Release Prep" one and an unscheduled Backlog) with target dates, rather than sitting in one open-ended backlog. The point of the date wasn't to hit it under pressure, it's a solo project, nobody's getting fired.
It was to force a regular question: does everything currently assigned to this milestone actually fit before the date, or does something need to move to the next one? That's a five-minute conversation with yourself every so often, instead of discovering three weeks in that the milestone was never going to fit and nobody noticed.
Chunking
The consistent pattern across the whole tracker: nothing stays as one big issue for long. A visual overhaul becomes five issues. A large feature becomes a handful of PRs, each one mergeable and functional on its own, rather than one branch that lives for two weeks and merges as a single wall of changes.
This did a few things: kept individual PRs reviewable (even reviewing your own diff is a different, better process at 200 lines than at 2,000), kept progress visible constantly instead of in occasional big lumps, and kept momentum and next steps clear, turning a vague "do x" into an actual, plan-shaped chunk of work.
Where AI pairing fit into this
A meaningful share of the implementation work on this project was done working with a code agent as a pairing tool. UI work has never been the favorite part of the job, Apple-native UI even less so, so having help there mattered: research agents prepping material for menu bar implementation details, or coding agents handling a minor change while attention moved to the next feature.
AI was used directly for writing and iterating on code, researching macOS's native permission boundaries, finding a simple test framework for the app, and running the build/verify loop in a sandbox to test changes in isolation from local quirks, among other things as the project went on.
The tracker and documentation didn't change shape because of it. If anything, the discipline mattered more: issue-driven work, tagged titles, PR-linked closes, and the "don't build without an approved design" rule all apply just as much to an AI-assisted change as a hand-written one. The process is what kept fast iteration from turning into fast drift, and gave each AI task real boundaries to work inside. Without that framework, the usual outcome is the usual outcome: vibe-coded, half-functional projects.
The tradeoff
This is not a heavyweight process and it isn't supposed to be. There's no burndown chart, no velocity tracking, no retro doc. This process could not support an enterprise-scale client, and would likely not satisfy most client work either.
What it has is every piece of work traceable to an issue, big efforts broken into chunks instead of one intimidating ticket, a sense of urgency driving the project forward, and a recurring nudge to check whether the current work still fits its target date.
That's close to the minimum viable version of "organized," and it was enough to take a project from an empty repo to a working v1.0 MVP without losing track of what was done, what was in flight, and what was next.
The project isn't over. It's a regular part of the stack now. The MVP and v1.1 have shipped, Public Release Prep is the current push, v1.2 and v1.3 are lined up behind it, and there's a backlog waiting to get sifted into whatever comes after.