Planning decides what deserves attention. Operations turns that decision into software that reaches customers and keeps working afterward.
We want as little machinery between those two things as possible. Projects need clear ownership, branches should become running environments quickly, releases should happen continuously, and the people building the product should stay close to what happens in production.
Projects create the boundary
Meaningful work belongs to a project with a clear DRI.
The project holds enough context for the team to understand the objective, current state and important decisions. We use Linear for this, GitHub for code and review, and Slack for conversation that needs to happen synchronously.
We do not try to reproduce the same information in every tool. Linear is the durable project index. GitHub describes the implementation. Slack helps the team coordinate.
The tools can change. The important part is that ownership and the path to the current source of truth are obvious.
Branches are working environments
Work starts on a branch and becomes testable as early as possible.
Our branch infrastructure gives the team a live preview and isolated data environment, which means product, design, engineering and coding agents can work against something much closer to production than a mock or local-only implementation.
The pull request becomes the unit of review. Sometimes the author is an engineer. Increasingly it may be a designer or PM using codegen, with engineering reviewing the parts that require deeper technical judgment.
Who wrote the first line of code matters less than whether the change meets the bar for production.
We prefer small branches that can be understood, tested and merged quickly. Long-lived branches accumulate divergence, hidden assumptions and integration risk.
Release when ready
Planning happens in cycles. Releases do not.
A feature should reach customers when it is ready, whether that takes two hours, two days or several weeks of incremental work.
The main branch should remain releasable. Preview environments let us exercise changes before merge, and automated checks should catch the failures machines are good at catching before humans spend attention on them.
Large features do not need one large release. Feature flags, incremental rollout and narrow vertical slices let us separate deploying code from exposing behavior to every customer.
This is particularly useful for AI systems, where model behavior and production traffic often reveal things that cannot be learned from a staging environment alone.
Quality is not a phase
We do not hand work to a separate QA function and consider the job done.
Quality belongs to the people shipping the change. Automated tests, type checking, evals, static analysis and coding agents can increase coverage, but none of them remove the need for product judgment.
For deterministic software, that means validating the important states and failure modes. For AI features, it also means evaluating model behavior, tool use, latency, cost and the quality of the final outcome.
A feature is not finished because the code merged. It is finished when it behaves well for customers.
Bugs compete with features
Bugs are product work.
Each pod has an engineer responsible for incoming bugs and operational issues during the week. Product reviews the queue with them and helps decide what deserves immediate attention.
We do not allocate an arbitrary percentage of every cycle to bugs. The amount of attention follows customer impact.
If the bug load is light, that capacity can move toward technical debt, small product improvements or de-risking future work. If production is unhealthy, feature work should lose.
This keeps operational work visible without requiring the entire team to context switch whenever something goes wrong.
On-call needs authority
The person on call needs enough context and authority to make the first call.
We use severity to communicate impact, not to create ceremony:
- SEV-1: Critical outage or loss of core functionality affecting a large part of the customer base. Immediate response.
- SEV-2: Significant degradation or failure of an important capability affecting many customers.
- SEV-3: Material but contained issue with a workaround or limited customer impact.
- SEV-4: Minor defect, cosmetic problem or low-impact issue that can enter normal prioritization.
Severity can change as we learn more. The first job is containment and communication, not arguing about the number.
The incident should have one clear owner and one place where the response is coordinated. Pull in the people required to restore service, keep the wider team informed when necessary, and avoid turning an incident into an all-company group chat.
Afterward, spend effort on the failure in proportion to what it taught us. Serious or repeated incidents deserve a written review and changes to the system. A trivial one does not need a ceremonial postmortem.
Close the loop
Production is another source of product information.
Support tickets, traces, logs, product analytics, AI eval failures and direct customer feedback should flow back into prioritization. A release is therefore not the end of the development loop. It creates the evidence for the next decision.
The operating loop is:
AI can accelerate several parts of that loop, but it does not change the responsibility underneath it.
Build it. Ship it. Watch it. Fix it. Learn from it.