> Setting our standards early on in a project, when we're most ignorant, guarantees we'll be setting the bar wrong.
This seems like an artificial constraint, there are obvious basics such as
- Code should be reviewed by N people
- Testing should cover X core workflows/Y branches etc.
- Dev environments should be creatable in X minutes/hours/days
- The system should perform specific tasks (if you don't know what these are, then coding the system may or may not be the best use of time)
- The system should support Y TPS at Z cost (all systems have a maximum scale, estimate the scale that is required).
- Design should be signed off on by Y people, where Y may be 1 person in a small team.
etc. You can find the right set of constraints for your domain. However a system not doing something it wasn't designed for isn't really tech debt in my opinion, it's just a new use case which needs to be built for.
Sure, those are the obvious and common standards everyone needs. However they are mostly useless and easy to change if you get them wrong. The heart of how your code is designed needs to be got right up front and you don't generally know - yet - what it should look like.
I agree that we can take some stabs at some standards early on. Indeed, we should. But to think of them as then done and dusted for the life of the project is a big mistake. Indeed, I'll note that you left the variables variable for a reason. And you picked things that are extremely broad, applicable to any project. But the kinds of standards that go into deciding whether something is the correct design are generally much more specific to the language, to the frameworks, to the people involved.
aye - I kept things broad as ultimately circumstances are going to dictate a lot. The point is that it's important to decide these decisions prior to starting the project. I've seen more than a few engineers throw the term "tech debt" around as a justification for rewriting everything to their preference. Practically, these folks will often leave the organization prior to any meaningful benefit materializing from their work. This pattern is somewhat inevitable given the time to complete a successful full rewrite is ~2-3 years for a non-trivial application, and the time for an engineer to remain with an organization is on average 18-36 months.
There is a balance to all things, but I tend to only view tech debt as "work that we agreed that we needed but couldn't fund, and/or intentionally defered."
>The point is that it's important to decide these decisions prior to starting the project.
It really isn't. Again, that's when the least is known. I think a much better point to set a particular standard is when there's some sort of team disagreement that would be solved by setting a standard. At which point you'll have more information than you would have had before starting.
> I've seen more than a few engineers throw the term "tech debt" around as a justification for rewriting everything to their preference.
Sure, and that's bad. But it's bad because there's a dispute over the team definition of "good design" that needs to get resolved by the team. One way to avoid that becoming a massive problem is to regularly set/update design decisions as circumstances demand it. Because sticking with bad or out-of-date choices made before the project started is a good way to create the sort of tension and chaos where "rewrite it all in shiny new framework X" can seem like a good idea.
> It really isn't. Again, that's when the least is known. I think a much better point to set a particular standard is when there's some sort of team disagreement that would be solved by setting a standard. At which point you'll have more information than you would have had before starting.
This probably depends on the size of organization, and the likelihood that the product will survive long enough to require such revision. In my line(s) of work, the odds have been high and it's proven critical to make sure these points are clarified early. If the project is likely to be canned in 6 months anyway... then people can do whatever they want :)
While this stance is fundamentally Anti-Agile, I don't see this as a problem. While Agile's emphasis on rapid iteration is correct - my experience has been that folks forget the importance of testing a meaningful hypothesis or achieving a meaningful milestone in these iterations. In a vast number of domains, it's much easier and more effective to do detailed design work then jump straight into coding. The design process should hopefully land the team on the correct thing to build, how they are going to build it, and why they are building it.
This seems like an artificial constraint, there are obvious basics such as
- Code should be reviewed by N people
- Testing should cover X core workflows/Y branches etc.
- Dev environments should be creatable in X minutes/hours/days
- The system should perform specific tasks (if you don't know what these are, then coding the system may or may not be the best use of time)
- The system should support Y TPS at Z cost (all systems have a maximum scale, estimate the scale that is required).
- Design should be signed off on by Y people, where Y may be 1 person in a small team.
etc. You can find the right set of constraints for your domain. However a system not doing something it wasn't designed for isn't really tech debt in my opinion, it's just a new use case which needs to be built for.