Whether you're a coder, or a librarian, or a janitor, take pride in your work. Do the best job you can.
If everyone else's code looks like crap, that's on them. When new people come on, they'll see your work compared to the slackers, and start emulating you, not them.
Like anything in life: Do the right thing, even when you're surrounded by villains.
I'm not saying code quality doesn't matter, of course it does. But there is a bigger picture and if you don't take the time to become a part of that you will not be very relevant.
"If it's just a stepping stone, then be fascinated by the shape of the stone"
-Ze Frank
That's a tiring way to live life too. If you're surrounded by villains, you should try to leave and go to a place where doing the right thing is easy. If at all possible.
An engineer once told me he cried with joy when he saw the interface and used some subsystem I had written a year earlier (in C, for an embedded system). So, I encourage you to write such great, beautiful code that other engineers will cry with joy when they behold and maintain it.
I'm junior enough that I often don't know what to do. I've never gotten really good at full unit testing for example. I really do think in situations like this my best bet is trying to find somewhere where they follow better practices.
> High standards for workmanship and worker safety are luxuries, but even some people who have the benefit of access to good training and safe workplaces don't take advantage of them. You shouldn't be ashamed of striving for the highest quality work you can do — instead, be thankful that you know what to strive for, and pass on your craftsmanship to anyone who is willing to learn.
http://www.reddit.com/r/Welding/comments/1z9oc1/serious_how_...
Almost always the answer will be no. So you're forced in a way to ship bad code.
I regularly come across months-old new code that the main team wasn't even consulted about. Reinvented caching layers, eval'ed code in database tables, file-download endpoints that accept any path from the browser, and code with so many immediate red marks that the writer can't possibly have been using an IDE.
It hurts my pride that I've been here for years and can't seem to change the pattern, but perhaps at some level it's basically codependence [0] and I have to leave the sick corporate-entity until they really "want to change."
Quality code is it's own reward. Yes, clean code is more fun to write and work with. But, just think of it as a different kind of optimization problem. If the investment is not going to pay off in the future, then it's not worth doing in the first place.
PS: This is not giving up, it's about getting even better by becoming ever more flexible.
whoever works with you will have to bear the burden that you left behind because you think its a low ROI for YOU
We aren’t dealing with anything new in terms of work ethics and quality control in software development. I maintain my code quality the same way a carpenter 2,000 years ago would have cared about how well the insides of a finished product are designed, whether it exceeds its required specifications, what other carpenters would think of their work, how they would feel if a future apprentice or master saw what they created that day, and so on and so forth.
Additionally, I place a premium on “skills learned or perfected” over “bugs closed or features implemented.” If xx is better implemented via an approach I haven’t used before - well, here’s my chance to learn how to do that. Sure, it’ll delay the process. But that’s where technical debt comes from. I may only end up writing ten lines of code that took me 17 hours to figure out and understand, but if those are the right ten lines of code then whatever else I could have or would have written or accomplished in those 17 hours doesn’t matter.
When the goal is “closing JIRA issues or GitHub PRs” and the only metric is how many bugs you closed that day, code quality will suffer. But instill that sense of pride, take ownership in your work and create an environment where others are encouraged to do the same, and it’s a different matter.
I think the problem is are you saying this as an individual or are you saying this as someone in leadership with power.
Place a premium all you want. But if you're a grunt, that opinion is going straight to dev null.
This is very good reward system for developers . placing a premium on “skills learned or perfected” over “bugs closed or features implemented”
> We aren’t dealing with anything new in terms of work ethics and quality control in software development. I maintain my code quality the same way a carpenter 2,000 years ago would have cared about how well the insides of a finished product are designed, whether it exceeds its required specifications, what other carpenters would think of their work, how they would feel if a future apprentice or master saw what they created that day, and so on and so forth.
> Additionally, I place a premium on “skills learned or perfected” over “bugs closed or features implemented.” If xx is better implemented via an approach I haven’t used before - well, here’s my chance to learn how to do that. Sure, it’ll delay the process. But that’s where technical debt comes from.
Then the gardening phase begins, which means no refactoring or warning or style fixes unless you touch the code to do something meaningful like a feature or bug fix. Leave everything you touch better than before. Dissolve big classes and functions into smaller ones. Write a test or two for the smaller side effect free function you just created.
It takes a ton of time and patience but every week the kraken loses a tentacle. And once most code feels untangled you can embark on a refactor since all of the parts are movable now.
Please advise.
You either go insane, give up and take up beekeeping, start your own company or finally decide to not give a shit anymore and start hacking the same way as everybody else because in the end your are not sending astronauts to Mars, and it works "most of the time" is good enough for the clients and the price and time they are willing to pay.
There's just no way around it. If your managers won't freeze the project until you make meaningful progress, you're going to be stuck working with this ugly code for a long time. Try to convince them that in the long-term a cleanup will pay dividends. Without their support though, you won't get anywhere.
If you're able to freeze the code for a bit, it sounds like it might just be quicker to rewrite some parts like the CSS. Don't take on the whole project at once - find pieces that can be rewritten individually, even if it's a large part like all the styling.
Understand that previous developers might not know what a DOM is have likely written ad-hoc jquery snippets, included 3 different versions of jquery-ui until they happened across the right combinations of versions to get their plugins to play and will have a mentality of "it was working".
Given that, here's some advise on how to stay sane:
1. Read and "Digest Working Effectively with Legacy Code" but accept you'll likely not be empowered to actually implement the changes.
2. Understand you'll have a grace period of ~6 months where you'll be far more empowered to make changes and get suggestions pushed through, after which you'll likely find yourself worn down by the system and more accepting of the status-quo. Leverage this time if you can.
3. Try to identify what caused the product to get to the state it is so it can be avoided for future products. If it's something you're not empowered to change such as "bad hiring policy" try to work out how you can spot that in future interviews.
4. Be pro-active in looking for bugs, particularly security flaws. Finding an IDOR which lets you get cross-account data is usually fairly straightforward in these kinds of environments. Doing so gets you noticed so you're not just another cog in the system and can provide real value. Be careful not to put others' out too much while doing this. It sounds like you only work on the front-end but even what appears to be front-end can have security implications such as template-injection.
5. Draw a line in the sand. Be entire accepting in legacy code but if someone is working on a new part of the product or is fixing a bug in legacy code be absolutely ruthless in what you'll let passed in code review. This may not do you any favours socially but a reputation for harsh code reviews isn't all bad. For one thing you'll have to do fewer code reviews.
6. Don't bite off more than you can chew. Treat it like a giant knot and don't be tempted to pull at threads unless absolutely necessary. Instead wait until given strong reasons for refactoring.
Edit: formatting, because HN doesn't do markdown.
As engineers we have a responsibility to raise concerns about bad practices and projects that have been neglected this way. Doctors raise concerns about hospitals, lawyers raise concerns about firms and enterprises, structural engineers raise concerns about buildings and infrastructure. Software engineers should do the same, resigning in protest if need be.
Rule 2: One bullshit hack must be removed per sprint.
Over time, you'll have better software.
The reason people like to default to linting when "fixing code quality issues" is purely because it's 100% objective and measurable, not because it picks up the truly important issues. It doesn't.
Edit: I am aware that coders have OCD impulses which can be sated with a linter, but priority #1 when fixing spaghetti code is unraveling the spaghetti, not sating your need to see }s in a place that makes you feel better.
My guess is that, when you have a cosmetically messy code base, people start to develop a lower standard for what counts a understanding the code they're reading. Probably as a self-preservation mechanism. There's only so much time in a day.
What language are you using? Dynamic languages are fairly difficult to meaningfully lint because it's hard enough just to analyze a function for problems, let alone extend past that. Static languages are easier to write non-trivial linters for, because there's more information just sitting there in the source, waiting for something to grab it.
But even for dynamic languages, linters can still do things like enforce documentation standards, code testing/coverage standards, and some other basics that may sound trivial, but still add up to very useful things.
But the bigger point is that you reduce merge conflicts since you won't have all sorts of unrelated formatting changes mixed in with the real changes.
I think that ideally, linting and especially formatting help quality by taking the trivial issues off the table. If your code is currently "clean", and the tools reformat or flag the code that you just wrote, then hopefully those issues will never be committed into the repository, so human code review can be about substantive points.
I work with a lot of legacy code and have felt overwhelmed at times by all the different coding styles that have been used through the code base and not know when to refactor or simply clean up.
Over the last year or two I've been using a linter to help me with all this. Basically any code I touch gets cleaned to the point the linter isn't complaining. This is usually a fairly quick and fun process and I've actually learned a lot along the way.
I would refactor as soon as too many things were touching and the code started to have a smell about it even though the linter wasn't complaining.
It has made maintaining legacy code more fun (almost like a game) and given me some better practices when moving into new code.
1. The problem starts with culture. These organizations are run top-down by people who don't understand coding. Sometimes they are ex-engineers, but that's usually about as good as non-engineer.
2. These organizations are systemically incapable of determining good work from bad. Who on the team is performing and who isn't? They can't tell. They will usually default to seniority (meaning how long a developer has been with an org, not how good they are).
3. These organizations reward fires that are put out. They do not reward fires that were prevented from happening in the first place. Those "senior" developers will frequently be rewarded for putting out fires they caused.
4. If you do a lot of work that prevents fires and that means you weren't working on features or bugfixes, you are going to get punished, not rewarded because to the people above you it looked like you were doing nothing.
5. If you're going to do this kind of work, you need serious intrinsic motivation.
I'm getting really tired of the message from management of "Here's what we should do, here's why we should do it, and here's why we won't."
In other words, they will periodically acknowledge that there are systemic and cultural problems that seriously need to be addressed, but consistently fail to address them.
Only certain types of people achieve seniority in a toxic organization, and they are typically those who (deliberately or incidentally) benefit from the culture that everyone else hates. They build a clique and try to build influence while the new hires -- who actually care about doing things well -- turn over every 3 months.
This is all anecdotal, of course, but I do think that in an engineering-hostile organization, the senior staff should typically take the brunt of the blame (just as in a successful organization they would take the lion's share of the credit).
If the quality of the software is slowing down feature releases, causing fires but is not being measured, you can make some headway with presenting ways to measure code quality so that your work shows up on their radar. This is difficult with such a subjective word as "quality" but tracking number of fires of time would be a good way to show that the way you develop is better than other people.
The other thing that companies miss are employees that help other employees in a mentoring sort of way. These people essentially cast a buff on everyone they work with. These buffs can be in the form of better tools, improved workflows, recommending reading material, new technologies etc. Unfortunately it seems this is up to that person's superior to recognize their value and fend for that person to upper management. I feel like it's easy for me to identify peers that cast buffs but not sure how easy it would be for a manager to identify such characters.
You can also ask during interview about the coding experience of the manager you will report to. Usually they are up front about it. If you turn them down, do us all a favour and let the company know that was why (more coding managers and fewer MBAs please!).
I'm not gonna lie, it's not going to be possible for everybody to avoid this kind of company, especially in the more backwater places. I left Singapore because I basically found one company that didn't obviously follow that pattern. They frustrated me too for other reasons so I didn't take their offer.
I think that this is one of the most underrated reasons for the formation of technology hubs and one reason why Singapore, in spite of really trying to become a "silicon valley of asia" (VC money: check, money pumped into education: check, huge startup grants: check) just won't, and will bleed rather than attract talent.
Needless to say, it's time for a move upward and outward.
Is it just me, or is less that four years not "really old"?
By the tone of the article, the author is clearly talking about the second kind.
Java code, C++ and python from 2014 could be untouched and still working fine.
Software does not age well when it isn't constructed properly.
"They're writing legacy code, man!"
So far they're about 2-3m in trying to replace us. Never gets far. Worst managed company I've ever seen. And as a consultant/contractor for 25+ years I've seen a lot of horribly run companies.
Downvotes are usually reserved for when a comment is low quality or not relevant to the conversation at hand. Could you please explain if my comment fit into these categories for my own learning? Thank you.
Given that we need a lot of housing and we don't have many home builders, there are a lot of tents floating around this industry.
It takes a lot of effort to keep cross-platform support while continuously improving it. Granted, not every project deserves that kind of effort, but I respect the effort it takes to keep software up-to-date.
That line wasn't the important part of this post. This one was:
> You should also have a global self-development plan. If you can’t put it into practice under the scope of the project, you should spend your free time on it.
Damn straight.
If you work somewhere with tight deadlines and rubbish code quality, and you're just sucking it up and writing rubbish code, you're part of the problem.
You should always have a plan about how to become a better more effective developer where ever you end up working. Sometimes that means plan to spend 10 minutes a day talking to your project manager. Maybe review code the last 1/2 hour of the day. Maybe make some internal tools to help automate your job.
Don't just sit there and be miserable; if your job/company sucks and you can't find a way to change it, at the very least make it a stepping stone to something better.
Some idle advice from my experiences working in places which sucked:
- If you write code, it should be good code. Even if other code is bad, that's no excuse to stop caring.
- ...but, you dont need to refactor that. Just do what you have to do, and make it as good as it can be under the circumstances. Don't break other things when you make things cleaner and better; that makes PMs think that 'good code' = 'break features'. Disaster.
- If you ship rubbish to 'come back and fix later', you'll never come back and fix it.
- Don't just comment out code and replace it a quick fix. Don't [Ignore] failing tests. If code is going away, take responsibility of actually delete it.
- Don't leave 'TODOs' in your code; either do it, or don't. No one is ever going come back and do your TODO. Not even you. That's what issue trackers are for.
- Some developers don't like running with 'trainer wheels' or 'guard rails' as they refer to unit tests. Ignore these people. Always write tests. The worse the place you work is, the more desperately you need those tests.
- Project managers (unless utterly incompetent) don't care about deliverables per se; they care about managing expectations. Estimate. Review your estimates. Try to deliver on your estimates.
- Don't work overtime unless it'll actually make a tangible difference for a specific deadline. :)
I would change the last point to: Don't work overtime unless you, personally, get something out of it. That something might be not getting fired. But if it doesn't get you anything... Don't do it.
// Copyright (C) 1991 - 1999 Rational Software Corporation
I think it actually originated in 2002 and those are junk left over from the use of Rational Rose code generation. Revision history only goes back to 2007.
Perhaps a former programmer deleted the revision history when they were about to move into a management role at your organization. I once stumbled upon a manager's name in the history of a 1970's Cobol program which had a goto statement every 5 lines, and it usually took half a day to make a simple change. All of the other similar-looking programs had had their history purged. When I showed the history notation to the manager, the look on his face wasn't nostalgia but fear.
In the JS world 4 years is very old bu in the C/C++ world 4 years are still quite fresh.
software isn't old until it breaks 10 yrs!
This is something I still struggle with. I think it's a result of an open source tool (GitHub) bringing bits of culture along with it.
In open source world, all contributions are entirely voluntary, and most follow the Benevolent Dictator For Life form of governance. So you do a bunch of work, and you submit a polite request for the BDFL to pull your work into the project. He or she may decline your Pull Request, request a long list of changes, or just wait ten years to give any response at all.
In a business setting with hourly pay, deadlines, and co-workers chosen for you, not by you, it makes less sense. People tend to wait until the last minute to give or request feedback which leads to a lot of thrown-away work. Unfortunately, willingness to throw away work becomes a mark of pride at some places. Maybe enterprise projects need some kind of "managed push" system instead of a "pull request" system.
Edit: "Unfortunately, willingness to throw away work becomes a mark of pride at some places." to elaborate, the thing that makes this unfortunate is that the person assumes that throwing away work is necessary for code quality to stay high. By requesting feedback at intervals (which is what the author of the article recommended), you can avoid throwing away work without sacrificing quality.
There are meaningful comments, but usually people have to fill their review quota.
Lowest hanging fruit should be just an in-place edit that would be automatically retested and that a reviewee can easily take as a patch and check himself. Instead of the back and forth bullshit.
It's a bit funny that placing a red herring comment that anyone can safely comment on makes the workflow faster. It's like this story about an artist who would place something ridiculous so when the time comes the CEO would just say: "It's good, just remove the thing".
Usually, it is some combination of a and b. All cases are an indication of a deeper problem. None can be fixed by calling your "pull request" a "managed push" nor by giving people unrestricted access to pushing code. It's typically either a problem with communication or priorities/expectations.
Is this a typo for "willingness"?
Code review is important not just for preventing junk from entering the codebase but for ensuring that someone else has seen the thing and has some idea of how it works. I agree that "pull request" is the wrong terminology for a commercial environment.
For example, you mention waiting until the last minute and throwing away work. If this is such a big deal, maybe the units of work are too big or too loosely defined. Loosely defined as in "eh, we never needed this in the first place" or big as in "sorry about that but your 2000 LOC commit just isn't the right approach". Maybe github style reviews/pull requests are also not the best way to go about it. IMO the github style is pretty weird and shouldn't be conflated with reviewing in general.
At my current workplace, we use gerrit to review every commit. The only way that they'll ever get to master or a shared development branch is if they get a +2 vote. Maybe this is closer to a "managed push"? It's not rare that someone finds an issue, and when that happens it's very rare that it means scrapping the entire patch, and when that happens, it's usually a very small patch for a problem/feature that ended up being fixed elsewhere, so I definitely don't think it's a waste of time. Instead I am grateful that many of the patches didn't enter the codebase in their initial state.
What would you do different in "managed push"?
Erm ... GitHub is entirely proprietary!?
(paraphrased from some original quote I can't remember)
Quality needs to be infused all across the board and needs to be reinforced from the management downwards throughout the whole organization, not just in the quality control department.
So Ford was definitely on to something and beat mr. Demming by a couple of decades on that particular insight. It's no surprise that both of them had a lot of these insights in the automotive industry to begin with, where warranties can very rapidly eat up the profit margin on the sale.
I’m drawn to this because they are two different mindsets that achieve somewhat conflicting goals, and the tasks can be separated with minimal communication overhead.
Thoughts?
Once there are two or more interacting layers of code, it gets really hard for the refactoring to catch up. If you fix a bug in a basic layer, the leaves of the codebase break. If you fix a bug in the leaves, you never get to refactor the core. If you want to stop the world and refactor everything at once, you get in the way of your quicker counterpart.
Or think of a multithreaded codebase without any synchronization. It definitely works well enough for demoing an "almost finished" product, but cleaning it up requires a lot of time and can introduce temporary regressions (deadlocks) that are worse than the bugs that the cleanup is supposed to solve (very spurious data corruption). It's a bit like the bullshit asymmetry:
https://twitter.com/ziobrando/status/289635060758507521
Ruby on Rails (from the OP) makes it easy to build many kinds of maintenance deathtraps.
The problem is that the guy making the mess gets credit for things and the guy cleaning it up keeps bad things from happening because of him. If your boss is not just the right type then you will become the bus tribute.
Now it's different (outside of HW orgs), but as I look out a decade or so, I'd rather have a part-time retirement job "cleaning up" interesting projects than travel/consulting.
That is to say, many of the loudest proponents of code quality are the first to completely disregard the customer quality points in the product.
Yes, there are fun meta arguments about how higher quality code can let you deliver faster. Nobody is going to wait for you to get to that point, though. You have actual users and customers today. Their problem is not the code's intrinsic quality. Instead, they are trying to use the product. If you can't tie their concerns to visible metrics that you can move more effectively than someone else, then you are likely just yelling at your peers. Not helping your customers.
And please, do not make the mistake of thinking you can push massive changes without breaking things. You will cause regressions. Period. If the changes are truly needed, you will make up for them with more rapid progress afterwards. Don't punish your users, but don't lie to them either. Respond and get so that you can measure your impact before they contact you about it. Reach out, apologize and make right.
I think we just need to stop telling people that code without tests is an option. It is an integral part of being a software developer, not a nice-to-have afterthought.
Maybe tell them that double-entry bookkeeping doubles their workload and they could go faster with single-entry bookkeeping.
This is the problem. Testing is not easy, and many developers simply aren't very proficient at it. Worse, we often don't recognise that it is a separate but important skill.
Here's what I've found:
- Most companies don't actually care about code quality. This is especially true for the ones that hire me. The managers that bring me in would much rather play-act than make the systemic changes required for their teams to operate with improving quality.
- There are systemic challenges to code quality in these environments. Namely hiring practices, performance evaluation, and priorities (budget/timeline). Obvious.
- Nobody can explain the benefit of code quality in terms persuasively enough to managers that they will accept the cost. I've never seen it done. It must come from somewhere else. This is why companies with more technical people in positions of leadership tend to have this problem less IME. Frankly I think this is why we use words like "technical debt" either that or it's a tautology. There's an irrational lack of discipline in this area akin to credit card debt.
- Furthermore, software itself does not matter to these companies.
That last one is the most important and it is not meant to be normative. I'm not saying software is not of actual importance. I'm saying it is not treated in the company with any importance. Software development is viewed as a necessary evil, not as an opportunity for competitive advantage.
The difference between my clients who view software as a necessary evil vs. a competitive advantage cannot be understated. It is immense. Often these companies with different perspectives are competitors in the same industry! You can guess which ones are growing happily and which ones are struggling to cope with changes to their business.
There are companies where the ratio of "business" people to IT is 1:3 and they balk when you tell them they're essentially a software company.
"No, we're a mortgage company."
Ok how's that working out?
What I've decided is to start doing a better assessment up front as to the actual priorities and perspective within these companies when choosing a client. There are companies where the light bulb is coming on and it can be a blast to work with them. In the current climate I would advise everyone to just flat out avoid companies that don't see themselves as tech companies. Work for companies that see themselves as tech companies or are seriously trying to change that perception internally. You can find companies like this in all industries. You might be surprised.
I personally found that calling oneself a tech company is not a good predictor for good practices. Everything call themselves a tech company nowadays.
You should certainly assess what kind of clients you're facing to adjust your recommendations. However, I don't think that the work environment matters as a short term consultant, whoever pays on time and has the biggest pocket is a good client.
If you can't clean it now, write down everything you know about the system, all those little annoying assumptions that nobody else has documented. Do this for your own sanity.
Don't be afraid to rebuild something if that will get you out of a bind. It will be for your own sanity to do so.
The pragmatics of cleaning up code is for your own sanity, unless you intend to leave in the near future. In that situation, it will be someone else's problem. But remember that in your next job, you'll become the someone else.
But unless you get support for this from middle and upper management, you're fighting a losing battle. You can't fix the world from behind the scenes. I know, I've been trying for many years.
My immediate managers have always been supportive of this attitude, but since everyone above them is concerned only with "How fast can we ship this?", and has the attitude, "We care about code quality, unless that means we have to dedicate resources to it." and "We will gladly spent 10 units of next month's or next year's resources to save 1 unit of resources for this week's release."
I understand the pressures of business needs, and sometimes you really do need to ship ASAP and sacrifice features or the insurance of quality of a well-defined piece of your project for revenue's sake. But at some point, constant compromises point to flawed management.
It's a dysfunctional organization that doesn't let you write quality code without lying (assuming you are correct that this is ultimately counter-productive for the organization's goals), and most every dysfunctional organization I've seen is characterized by lack of transparency and truth internally -- nobody knows what's really going on, so there's nothing to do but political games. I think that lack of internal honesty is a cause, not just a symptom. So your workaround to let you do quality work despite being in a dysfunctional organization, misleading your peers and/or managers/administrators, makes the organization's dysfunction even worse, making it even harder to do quality work. In another kind of vicious cycle.
After a bunch of years of programming professionally, I've come to the conclusion that my job includes not just trying to make the code better, but trying to make the organization better too. The same way you've got to 'fight' for quality code, you've got to 'fight' for healthy (honest and respectful) organizational culture.
There are some (many) places that are so dysfunctional that they seem hopeless, and maybe you can't easily leave and find other employment. You've got to do what you've got to do to stay sane (and keep your mind from dying) and I don't fault people for their coping strategies in such an organization, but I think misleading/lying (which is really just a kind of 'political' game of it's own) to give you space for code quality is likely to lead into a vicious cycle of descending badness all around, not ultimately leading to increased job satisfaction.
In the end, if your superior tries to micromanage but doesn't understand the details, then a lie woven from bits of truth, if it helps achieve a goal, is morally indistinguishable from the whole raw truth.
1. If I don't get the time to do what I think is necessary, then I lobby to make sure that it's my decision about how much time it takes. You're not going to get handed this on a silver platter, but the main argument is that as a developer you are making a good salary. The person paying that salary should get the best value from that money. If you have to do your job in handcuffs, you're not going to be able to give the best value.
2. If I'm not in a political situation to do #1 (and you should probably try to make sure you are before you actually stick your neck out), then I will note the constraints I have to work under. Making a project succeed when everything goes exactly as you want it to is relatively easy (well, TBH, I think it's never actually easy, but you get my point). What makes a great developer is making the project succeed even when you don't have everything your own way. So find a way to succeed with the constraints that you have. If you fail, make sure to make it obvious which constraints are causing the most problems. Usually after you fail you can get some extra leeway on those issues. Work on the issues one at a time, most important first. Eventually you can usually promote yourself to option #1.
3. If I can't do #1 and there is some reason why #2 fails (and I can't fix it), then I will go elsewhere. No point in sticking around in a place where you can't succeed. Wish everybody great luck. Express remorse that you couldn't get the kind of success that everybody wanted. Thank people for the opportunities that you had.
4. If I can't go because I have no other job, or I need to stay because my visa says so, or my spouse will go crazy from stress if I switch jobs, or a million other possible reasons... I'll keep working and keep studying exactly what's causing the problems. It's easy to conclude, "Joe is breaking everything. I hate Joe" (I only picked the name Joe because to the best of my recollection, I've never worked with someone named Joe). But you're stuck and you might as well learn about the situation in more detail. Wait and watch. I hate waiting. Man, do I hate waiting. But eventually it will pay off. Opportunities are out there. Your job is to recognise them.
That's it. Don't lie. You'll only get found out and then make your job a hundred times harder. Don't get dragged into petty politics. The job is hard enough without drama. Play it straight and give everyone the best chance they have to understand what you are doing and cooperate with you. Don't undermine people. Just do your best. It's not always easy sailing, but learn how to navigate rough waters and you'll be fine.
Meanwhile, the same outsourced developers are making even more things you haven't found yet for whatever managers have the most political clout this week.
If you never get to version 3, you never get the opportunity to worry about code quality.
It's the classic bait-and-switch of corporate development. They get you in the door by pretending they have a rational process, and wait until you're invested before dropping the facade.
I, too, have never worked for a company that ever considered retiring software ahead of immediate necessity. Generally, it's always "we don't have time to do it right in the first place, because we're too busy fixing all the stuff that is broken right now."
please, for humanity, write documentation. even better if it's after the code is written. why does the payments-smart-broker have a direct connection to the translations database if it doesn't have a ui?