I’ve been at this for a long time, and regularly have to revisit my codebases (I have quite a few). I also tend to use many of the packages that I publish, in my own work (dog food). I write code that I want to see, six months down the road, and my bar is fairly high.
I am very familiar with various devops infrastructures, having maintained many systems that integrated things like Jenkins, JIRA, Confluence, Perforce, BitBucket, Bamboo, etc.
These are pretty much required, when working as a team, but they introduce some significant overhead, and not just in the work needed to establish and maintain them. They also introduce overhead into the workflow of each user of the system.
For my personal feature tracking, I use a PostIt pad, on my desk. I have a glass-top desk.
As I plan a feature or bug fix, I write it as a task on a PostIt, and stick it on the left side of my desk.
As I work on it, and consider the task complete, I move it to the right side of my desk.
Once I have tested, confirmed, and checked in the fix, I drag the note to the trash (under the right side of the desk). I use the commit comments to codify any historical notes. I will, sometimes use a GitHub Issue to codify something for historical stuff; especially if it's something that a "non-me" stakeholder is interested in, but the PostIt for that issue is what I use. I think the largest number of PostIts that I've had, over the last couple of years, has been 4.
This only works for two main reasons:
1) I’m really experienced, so I’m pretty good at estimating and wargaming the tasks; and
2) I run in what I call “constant beta.” That means that I don’t move on to a new task, until I am satisfied that all bugs have been fixed; even the small ones. Incomplete implementation is not usually considered to be a “bug,” but it depends on the current context. Bugs don't usually last long enough for me to write them down. I'm fairly efficient at problem-solving.
#2 is a biggie. My apps are generally at “ship Quality,” almost from the start, although incomplete.
This allows tremendous iteration, especially in receiving feedback from non-tech stakeholders (I can start using TestFlight to share releases, from the very earliest stages of a project).
It also prevents those disastrous “Oops, we didn’t think of that in our project planning” issues, and also pretty much guarantees a smooth, surprise-free final testing phase.
This is especially useful, when you have a small, distracted team, like many volunteer and nonprofit orgs have.
But this is what WFM. YMMV.
You can see for yourself, how I work: https://github.com/ChrisMarshallNY#browse-away