In 17 years of writing code and leading teams, I’ve slowly built a list of software development rules. These rules allow high-quality code to be written quickly. I ask every engineering organization I lead to follow these rules.


  1. Write simple code that a freshman computer science student can understand. In general: the simpler, the better. A peer should be able to understand your function in 15 seconds.
  2. Name symbols – variables, functions, classes, filenames, etc. – precisely and exactly.
  3. Add a 30,000ft comment at the top of every file, explaining what the file is and why it matters.
  4. Use clear, plain English when writing comments.
  5. Explain the purpose of every function with a comment before its signature.
  6. Comment every step in non-trivial functions. (Step 1, Step 2, etc.)
  7. Follow the linting rules. If you don’t like the rules, open a PR with proposed rule changes and get a supermajority of the team to agree.
  8. Use custom exceptions amply, so callers can catch errors confidently and application logs are traceable.
  9. Make no assumptions in your code. Don’t assume a public function’s arguments are safe; don’t assume API’s will be online; don’t assume rows will exist in the database; etc.
  10. Keep master release-ready. Master branch can never: a) add bugs or regressions, or b) temporarily remove existing features. Assume that production deployment may happen at any time, and master will go to production as-is.
  11. Zero-downtime is required. Wherever humanly possible: don’t write backwards-incompatible API changes; don’t write locking DDL migrations; don’t expect atomic deploys; don’t plan downtime.
  12. Fully remove unused code. If you remove code/features, all dependencies must be deleted. Never delete the view but leave the controller; never delete the controller but leave the route; never delete the model but leave the table; never delete the function but leave the pip package.
  13. Strongly prefer a global styleguide. Avoid per-component styling. Work with the design team to define styles in a top, global level styleguide, and then let those styles cascade to each component unabashed.
  14. Don’t use TODO’s. If possible: fix the code now. If that’s not possible: create a ticket for the remaining work that needs to be done, and include a link to that ticket in a code comment.
  15. Strongly prefer the tech we already use. Don’t use another language/framework/tool unless it’s absolutely necessary.


  1. A clear PR title that summarizes the PR is required.
  2. In every PR description include 2 things: (a) why this PR was necessary, and (b) what you changed.
  3. Write small, <100 line PR’s that can be deployed to production in baby steps. To avoid being blocked while waiting for PR review, daisy chain subsequent branches/PR’s so they can be reviewed/approved/merged in order.
  4. Make Single-Type PR’s. A PR is 1 of 4 types: a) refactor & reorganization, where no functionality is changed, b) adding a feature, c) editing a feature, d) deleting a feature. Every PR should be one of these 4 types, and your PR should declare which type it is.


  1. Devops code is still code. All the same rules herein apply.
  2. Avoid manually-executed code. SQL snippets, scripts, and one-time commands should be run programmatically (via migrations, background jobs, deployment pipelines, etc). When automation isn’t possible, create a checklist for every environment where the code needs to be deployed (each developer’s localhost and each hosted environment) and ensure the checklist is completed.
  3. Make DDL Edits via Migrations. Never make DDL changes in hosted environments manually.
  4. Check off checklists 100%. Rely on checklists to avoid oversights. Always complete every item on the checklist before advancing to the next project.


  1. Over-communicate. There is no punishment for asking too many questions or providing too many status updates.
  2. Break down the project. Before any code is written, divide the project into a series of baby steps, document the steps on a ticket, and have someone review/edit the steps before starting.
  3. Finish existing work, like tickets, QA, PR’s, emails, and code reviews, before starting new work.
  4. If you run out of work to do, proactively seek out what needs to be done next.
  5. Avoid religious crusades: tabs vs. spaces, emacs vs. vim, etc.
  6. Raise security concerns as soon as you notice them – either in production or during development.
  7. Treat PII and confidential information very carefully, as if it was your own.

Individual Performance

  1. You’re online and working, during the hours we’ve agreed.
  2. You’re available & reply promptly to chat & email, during the hours we’ve agreed.
  3. You push a branch/PR with some code every day.
  4. If you aren’t fluent in English, you continually improve your written and verbal English skills.