Skip to content

Delivery

Turning priorities into goals, tracking the work and releasing changes safely

I want to be able to explain why we are building something, what we expect to change for the customer and how we'll know it has worked. The work starts there, before we write a plan or open a pull request.

In planning and code review, our written process sounded reasonable while the work followed a different path. Some rules existed only because we had agreed them in a meeting.

Planning

Agree the direction for the next stage, then shape only the next few goals in detail. A plan written for three months in advance stops being true well before the three months are up, and the time spent perfecting it is time not spent learning from real data.

I would also put the person with the customer context and the engineer who will deliver in the same conversation from the start. We spent too long passing versions of a plan between them.

Our first plan started from a prototype. We divided it into modules and personas and tried to describe the whole product. Once we got real data from design partners, that tidy picture stopped being enough. We shortened the planning cycle so we could check what we were learning sooner.

Then, approaching launch, we tried to settle three months in detail again. The founders' version of the goals was too far from the engineering work; the engineers' version became too technical. By the third pass, I was trying to recover a clear account of what would be different for the customer. We had made the plan a document to pass between groups that needed to work through the same questions together.

In the retrospective, someone wrote, “I find planning confusing”. It received more votes than any other suggestion for improvement. Our latest process separates choosing the next goals from shaping them, so the planning meeting no longer has to produce a detailed month of work. These rules are still new.

How I do it now

  1. Project. We work in projects of two to three months. The founders frame the outcome, success measures, dates and constraints.
  2. Monthly Planning. On the first Monday of the month, everyone meets for ninety minutes. Before the meeting the project should already hold most milestones, each with a Lead, and goals with a Sponsor. A self-explaining title is enough. We do not shape goals before or during this meeting.
  3. In the meeting. We look back at what shipped and what slipped. For each milestone, people introduce the goals they added, in about thirty seconds each, and the team decides whether to keep, combine, defer or delete them. Then we pick the two or three highest-priority milestones and, for each, the goals to move from Planned into Shaping. Every team member should leave owning or supporting at least one active goal.
  4. Shaping. Straight afterwards, each Owner and Sponsor set up a meeting to shape their goal: requirements, boundaries, approach and how to recognise the result. The Owner keeps the original questions and their answers in the goal.
  5. Delivery. Once the plan is approved and dependencies are agreed, the goal can start when its Owner has capacity. Nobody waits for the next planning meeting.

The template I use to start shaping a goal is in Appendices. How we got here is in We Kept Trying to Plan Everything.

Keeping a goal useful after planning

For work this early, I would start by checking a real result within two weeks, sooner where the question can be answered sooner. A longer goal can still produce something we can examine: real data through the proposed path, a customer's response or a working part of the journey. The check should help us decide whether to continue, change the approach or stop.

I have also asked for implementation issues to connect back to the goals they support. Otherwise a milestone can contain plenty of activity without explaining how that activity contributes to the outcome. A useful review follows the link both ways: from a goal to the work needed to deliver it, and from a piece of work back to the reason it deserves time. I still need to check that those links stay complete as the work changes.

When new information changes scope, the Owner takes it back to the Sponsor for explicit agreement. When a priority changes, leadership needs to say which other work moves or waits. The board should then reflect that decision. I cannot keep asking for a new priority while expecting the old plan to remain a reliable promise.

An individual's development needs goals too. The employee and manager should agree useful, achievable goals, define the evidence they will discuss, and follow up as circumstances change. I would keep that conversation distinct from the delivery board. Someone's development should connect to the work, but it needs attention beyond whether a feature shipped. The practical review guidance is in People.

Goal tracking

Once a goal is under way, its record needs to stay close to the work, and someone needs to keep it current. Even a perfectly current board will not tell an engineer why a priority changed or who can settle an argument about scope. I treated visibility as though it would provide direction, and built a dashboard nobody but me opened. By October, I was frustrated that the team was not using it or keeping the GitHub board current. That story is in Ten Engineers, No Product Manager.

How I do it now

We work in projects of two to three months. A project holds milestones, and a milestone holds goals.

  • A milestone is an outcome that needs several goals to support it. It has one Milestone Lead and a due date, and it closes when its outcome is delivered and its goals are done. A project can have more than fifteen. That is intended, so there are small wins to mark along the way.
  • A goal is one shared description of one tangible outcome, its requirements and what done looks like. It belongs to exactly one milestone and has one Sponsor and one Owner, who are different people. The title should make the outcome clear to someone without prior context.

Inside a goal, the roles are written down: Milestone Lead, Sponsor, Owner and Supporters. A Supporter owns their agreed contribution, gets the context they need and brings progress to the Owner without waiting to be asked.

We do not track daily work on the board. Goals move through five statuses:

StatusWhat it means
Planned
A proposal. A clear title and a milestone are enough. Listing it does not commit us to delivering it.
Shaping
The Owner and Sponsor work through the questions and agree the plan: requirements, boundaries, approach and how to recognise the result.
Backlog
The written plan is approved and dependencies are agreed with the people involved. Whoever owns the goal starts when they have capacity, without waiting for a meeting.
In Progress
The Owner is delivering the agreed outcome. Each Owner has at most three goals in progress.
Done
The agreed outcome has shipped and is live and usable.

Dependencies between goals are recorded as “blocked by” relationships in GitHub. Being blocked does not change a goal's status; other obstacles are raised in stand-up. If a goal turns out not to be ready, it goes back to Shaping.

The limit of three goals in progress is a ceiling. I would not treat it as a target.

The board also needs a use that is worth keeping it current for. Mine became useful when we brought goal status into stand-up. Before then, the real work moved through pull requests while the board gradually drifted away from it. Adding more dashboard views did not repair that relationship.

I would start with the next conversation the team needs to have: which goal needs a decision, what is blocked, and what changed since we last looked? Keep those answers in the source record and use them in that conversation. If somebody has to reconstruct the answer privately before every meeting, the shared record still is not doing its job.

Shipping a change

In one thirty-day stretch, roughly ten of us merged 854 pull requests. With AI helping us build faster, the volume of changes had grown much faster than the time available to review them.

Review has to be something a person can do with care at the volume the team produces. An approval is easy to count. Whether someone understood the change is much harder to establish, and a process that only produces clicks makes the record look complete without making the software safer.

Not every repository carries the same risk. Treating an experiment like customer-facing software slows the experiment and teaches people that the process is a formality.

How I do it now

This is the model we are putting in place. Some of it is enforced in tooling and some is still being built.

  • Critical and experimental repositories are separate. Critical means the repositories that build, configure or deploy the product. Sandboxes, experiments and documentation-only repositories do not go through the production change gate. If an experiment starts serving customers, its controls change with it.
  • Pull requests are the record of each change.
  • Small changes. One of the engineers added a check that fails pull requests over four hundred lines, which pushes a coding agent towards small, stacked changes a person can read.
  • Automated review. A change gate reviews each pull request with several models, each looking at one concern: correctness, security, tests, the reach of the change and whether it can be reversed. It produces findings for the engineer to fix or explain. It recommends and does not approve.
  • Ordinary changes. The author can merge an ordinary change within an agreed goal once the automated gates pass and the findings are addressed.
  • Riskier changes. Large changes, and changes involving authentication, secrets, infrastructure or migrations, need a second engineer before merging. So does a change whose risk reaches outside the goal.
  • Choosing a reviewer. Authors choose whom to ask: whoever knows that part of the system or would spot what the author would miss. We tried automatic assignment from code-ownership files, and it sent people requests about code they had not touched in months, so we removed it.
  • Before production. An independent person approves before a change reaches production. Where a merge triggers a production deployment, that approval happens before the merge.

For when a change needs someone else at all, we use the vocabulary of Ship / Show / Ask. The history of how we arrived here is in Compliance at AI Speed, and the gate has its own post: Building a Change Gate for AI-Assisted Development.

Why I distinguish the rule from its enforcement

An early fix was simply to agree that the person reviewing a change would record their approval. We changed no configuration. It worked for a few months, then I checked and found merged pull requests without recorded reviews, including mine. Agreement had not made the practice dependable.

The change gate taught me a second lesson. During the pilot it could approve an ordinary change after its checks passed. Our auditor's guidance for our process was that the service could recommend but could not approve. We took it down that afternoon and brought it back the next day with that approval removed. The review findings were still useful; the decision to let software approve had needed changing.

I now want to trace a change through the actual path: who can merge it, which findings need an answer, what reaches pre-production and what stops it reaching production before the required independent approval. These are our chosen controls, shaped with our auditor, and I am still checking their enforcement.

Releasing

After review, I want a versioned artefact to move through a repeatable deployment path that the service owner can use without asking another team for routine steps. Recovery needs the same attention as deployment. Rolling back code does not undo a database migration.

How I do it now

Merging to main produces a version and a changelog from the commit messages. The release builds the image and writes the new tag into the service's manifests, and the deployment to pre-production follows from Git without a manual step. A rollback is a new deployment of an earlier version through the same path.

I found rollback harder than I wanted it to be, which is why I want recovery rehearsed. The four questions I ask about any release path are in Appendices, and the tooling is in The Engineering Foundations I Want in Place Early.

Rehearsing a failure before depending on the procedure

The exercise I would start with is one customer journey through deployment, a controlled failure and recovery in a suitable non-production environment. Have another engineer repeat it. The places where they need help tell us which access, explanations or tools are missing.

I would want them to identify what is running, find the relevant logs and metrics, and explain whether returning to the earlier version is safe. A deployment that changed data or triggered an external action may need a different recovery plan. The procedure should say when to stop and ask for help, as well as which command to run.

For now, this is the rehearsal I want us to run. We use incident tooling and have runbooks in the repository. How a change reaches production, how it comes back out and how an incident moves from the first report through recovery and follow-up are in Production.

As the company grows

In a startup, founders can shape goals and settle scope questions directly with the people doing the work. As responsibility spreads across teams, I would make those decision boundaries and dependencies explicit before adding more planning meetings. A team should know what it can decide, who supplies the customer context and which changes need another team's agreement. I would check the review and release path with each team too, so the written controls still describe how its work reaches customers.

Still to write

  • How well the newest planning rules hold up after a few months of use.