Manifesto
Our engineering principles start from a simple premise: in a startup, the ability to change quickly is the highest form of code quality. Every other principle follows from this, creating a framework for shipping fast while building right.
1. Changeability Above All
One true measure of our software quality we value is the ease and speed to change it.
2. Quality Code for Quick Change
Because of Point 1, code quality is key and a primary concern.
Code communicates intention 3. Ship Early, Ship Often
Because of Point 1, we release frequently and easily.
4. Test Behavior, Not Implementation
Because of Point 3, testing is imperative.
Test everything as early/left as possible Test behaviour not code flow Tests are the most accurate documentation of the functionality in a system Even simple tests document behaviour and add value If it can be tested without dependencies (i.e., in unit tests) it should 5. Left-Shift Over Late-Catch
Because of point 1, we should avoid duplicating testing coverage, shift tests left to make changes easier.
Prefer unit tests over integration tests and integration tests over end-to-end tests We should always aim to be at the stage where there is no risk to releasing 6. Bounded Domains Over Big Monoliths
Because of Points 1 and 3, we split the system into Domains
Because we split domains they are easier to reason about Because we split domains they are easier to deploy Because we split domains we increase boundary constraints Because we increase boundary constraints we need to avoid overly micro-servicing Because we increase boundary constraints, boundary contracts and versioning are a 1st class citizen Because we version and point 1, we can change the system easily, the boundary should only be concerned with mapping, not logic 7. SOLID Principles, Flexibly Applied
Because of Point 2, we follow S.O.L.I.D. principles
In particular Single Responsibility Prefer explicit over auto-magic but self-evident is even better 8. Pragmatism Over Dogma
Because of point 2, we follow common coding guidance but not dogmatically
We like K.I.S.S. but prefer "Everything should be made as simple as possible but no simpler" We follow DRY but understand it is often misunderstood and refers to logic and control and does not refer to lines of code "Currently looks the same" is not "Must always be the same by definition" 9. Refactor Without Permission
Because of Point 2, we refactor frequently
Make changes that don't affect functionality freely If there is no change to functionality, a ticket is not required 10. Clarity Over Debt
There is no such thing as a technical debt ticket
There are tickets for improvements that are awaiting infrastructure changes to be supported There are tickets for changes to be done now infrastructure changes have been implemented There are tickets for improvements to be done now we understand the feature and requirements better There are changes to improve established coding patterns - (Introduce these changes to coding patterns with an example and demonstration, then small refactorings to apply to whole domain gradually) Remaining, i.e., all that's left in technical debt, are changes that I couldn't be bothered to do 1st time round. We don't do these We don't have "definition of done" but align on "done done" at a feature level. The feature is done and will not need revisiting unless we learn something new 11. Boring Tech Over Bleeding Edge
Boring Tech is good and sufficient for Map Reduce
The majority of the interactions are Map -> Reduce -> State and State -> Reduce -> Map Generally we use HTTP and service bus and follow at-least-once guarantees Generally we use C#, TypeScript and React but follow a demonstrable best fit judgment 12. Velocity Through Accuracy
Because of Point 1, we will have velocity
Velocity comes from speed of change and accuracy With clear business intentions we will be able to work accurately Development is a scalable process and we will concentrate on making it more so Under time pressure it is even more imperative to work accurately 13. Enable Business, Don't Constrain It
Because of Point 1 and Point 12, the technology will not constrain the business
While the current technology may constrain/delay an individual contract, if we are able to change quickly it will not constrain the business as a whole There are 2 types of deadline: Imposed by outside authorities - federal, attestations, auditing, security etc. Internal and controlled by Straddle We will be able to plan for and handle the 1st type of external deadline When working with the 2nd type of deadline, the business will work with realistic but changeable timelines influenced by technology but not dictated by technology or set in stone 14. Everything Changes (Except This)
Because of point 1, anything, except point 1, is open to change - including this manifesto, technology choices, language choices and business choices.
The Core Philosophy
Our engineering team has established that the most important metric for code quality is "how fast can we change it?" This isn't about being sloppy - it's about recognizing that in a startup, our biggest risk is building the wrong thing. We optimize for learning speed over perfection.
What This Means Practically
Speed of Iteration: When market needs shift or customer feedback reveals new requirements, our team can pivot quickly. We're not building elaborate systems that take months to change.
No "Technical Debt" Excuses: We reject the common engineering practice of putting band-aids on problems and calling it "technical debt we'll fix later." Instead, we finish things properly the first time or clearly identify what's blocking completion (such as waiting for third-party services).
Using Proven Technology: We don't chase shiny new tools. Think of it like using QuickBooks instead of building a custom accounting system. We use boring, reliable technology so we can focus on building our product, not debugging infrastructure.
Smart Testing Approach: We test everything, but efficiently. Like quality control in manufacturing - checking at the component level rather than only testing finished products. This catches problems earlier and cheaper.
Business Implications
Deadlines: We distinguish between real deadlines (regulatory compliance, key customer contracts) and arbitrary ones. The team will move mountains for the first type but may push back on the second if it means cutting corners that compromise long-term velocity.
Team Autonomy: Engineers can improve code without asking permission for every small change. Like letting salespeople adjust their pitch without approval for every word. This keeps velocity high.
Domain Separation: Code is organized like company departments - sales, marketing, operations. Each piece can be updated without breaking the others. This means we can ship features incrementally rather than in big risky releases.
What to Watch For
Communication: With the freedom to refactor, engineers should over-communicate. "Heads up, working on payments today" prevents surprises. Business Context: These principles assume engineers understand why we're building features, not just what to build. Keep engineering involved in customer conversations. Growth Planning: These principles are perfect for our current size but will need evolution. Like how our sales process at 10 customers will differ from 10000 customers. The Bottom Line
Our engineering principles prioritize shipping features quickly and responding to market feedback over building perfect systems. For a startup in a rapidly changing industry, this is exactly right. We'd rather build the right thing imperfectly than the wrong thing perfectly. However, this only works if we build what we believe is the right thing, the right way. Fixing bad implementations is not learning.
Think of these principles as engineering's "operating agreement" - similar to how sales might have principles about customer response times or quality standards. They've codified how we make decisions so everyone rows in the same direction.