Handbook · Personal philosophy
How I write software.
The maxims I keep coming back to, the clean-code rules I hold myself and my code reviews to, and how I think about building software with AI. Most of these were learned the hard way, usually while on call.
← Back to nchilders.comGuiding maxims
- 00You will regret complexity when on call.
- 01Stop falling in love with your own code.
- 02Everything is a trade-off. There is no “best.”
- 03Every line of code you write is a liability.
- 04Document your designs and decisions.
- 05Everyone hates code they didn’t write.
- 06Don’t add unnecessary dependencies.
- 07Coding standards prevent arguments.
- 08Write meaningful commit descriptions.
- 09Never stop learning new things.
- 10Code reviews are for spreading context.
- 11Always build for maintainability.
- 12Always ask for help when you’re stuck.
- 13Fix root causes, not symptoms.
- 14Software is never finished.
- 15Estimates are not promises.
- 16Ship early, iterate often.
- 17Keep. It. Simple.
Clean code principles
Core principles
- Intentional naming. Prefer domain terms. Booleans start with
is,has, orcan. - Do one thing per function or class: a single reason to change.
- No surprises. Follow command–query separation and avoid hidden side effects.
- Fail loudly and early, with context-rich errors.
- Prefer composition over inheritance.
- Comments explain why, not what. Remove dead code. Every TODO gets an owner and a date:
TODO(name, date): …
Guardrails
- Functions stay under 25 lines, at a single level of abstraction.
- No more than 3 parameters. Beyond that, use keyword arguments or an options object.
- No boolean flag parameters. Split the method instead.
- Lines under 100 characters, with formatters running on save.
- Small, focused files, each with one public responsibility.
Encouraged
- Tell, don’t ask. Respect the Law of Demeter.
- Wrap third-party boundaries in adapters, and write learning tests for tricky libraries.
- Background jobs are idempotent. Migrations are safe and reversible.
- The Boy Scout Rule: leave the code you touch a little cleaner than you found it.
Rails
- Thin controllers. Domain services own the business logic.
- Name services by intent, separating reads from writes:
Invoice::Finder.findversusInvoice::Upserter.call. - Keep business rules out of model callbacks. Prefer explicit orchestration.
- Queries live in scopes or query objects, never inline SQL in controllers.
- Data backfills and jobs are idempotent and transactional.
- Avoid polymorphic type checks. Prefer duck-typed interfaces, such as a
recipient_counton every recipient type.
Ember
- Data down, actions up. Routes load data; components render and handle interaction.
- Colocate templates, code, and tests. Keep templates lean.
- Prefer tracked state over observers, and surface user-meaningful errors consistently.
Tests
- Unit tests target public APIs. Integration tests cover critical paths.
- Arrange, act, assert. Descriptive names. Don’t mock internals.
- Use factories and builders, pin behavior at the seams, and test that jobs and backfills are idempotent.
Errors & logging
- Raise specific errors, catch them at the seams, and translate them into API responses.
- Include request and account IDs in logs. Never log PII.
Building software with AI
I use AI every day, and I want every engineer I work with to use it too. It has made writing code dramatically cheaper. It hasn't made owning code any cheaper, and nearly everything I believe about AI comes from that gap.
It multiplies whatever is already there. Clear standards and good tests produce great output; a messy codebase gets messier, faster.
“The AI wrote it” is not an answer in an incident review. If you can’t explain it, you can’t ship it.
Generating a thousand lines is free. Reading, testing, securing, and maintaining them is not. Ask for the smallest change that solves the problem.
AI-written code goes through the same review, tests, CI, and QA as everything else. There is no fast lane.
The standards that onboard a new engineer are the same ones that make an agent useful. Write them down once and give them to every tool.
AI can draft options and argue trade-offs. Architecture, product calls, and anything touching customer trust stay with humans.
Where it shines
- Scaffolding and boilerplate that follows patterns already in the repo.
- Writing tests, especially listing the edge cases I didn’t think of.
- Getting oriented in unfamiliar code, libraries, and error messages.
- Mechanical refactors and migrations with a clear before and after.
- A first-pass review before a human one, and drafts of docs and commit messages.
Where I slow down
- Authentication, authorization, payments, and anything security-sensitive.
- Data migrations and backfills that run against production.
- Concurrency, caching, and other bugs that only show up under load.
- Architecture and dependency choices that the team will live with for years.
- Anything I can’t verify myself. If I can’t check it, I don’t trust it.
How I work with agents
- One source of truth. Team standards live in one place and sync into every tool’s instructions:
CLAUDE.md, Copilot instructions, Cursor rules, and the rest. - Treat it like a sharp junior engineer. Fast and capable, but it needs clear direction and a careful review.
- Assumptions out loud. When requirements are unclear, the agent asks or states its assumptions so they can be corrected before merge.
- Small steps. Small diffs and small commits, so every change is easy to review and easy to revert.
- Tests with every behavior change. If it changes how the software behaves, it comes with automated tests.
- Prefer boring. Consistent, obvious solutions that match the codebase beat clever new abstractions.
Hard limits
- Never swallow errors or rescue broad exceptions just to get the build green.
- Never disable linters, weaken tests, or strip guardrails to pass CI.
- Never put secrets, tokens, customer data, or PII into prompts or logs.
- No new dependencies without a clear need. Each one adds audit and upgrade work.
These are my personal principles, not the official standards of any employer.
Like how I work?