Organizing Execution
Implementing a Vertical Slice: From Intent to an Accepted Result
How one vertical slice is carried through the whole workflow, from a user's intent through scope, agent brief, data consistency, evidence and review to…
Vertical Slices already defined a vertical slice as a complete behaviour that passes through whichever parts of the system it needs. This unit does not repeat that definition, and it does not build a project for the reader. Instead, it follows how an author takes one slice through the workflow: clarifying the intent, narrowing the scope, preparing a safe environment, handing changes to an agent, checking them, responding to a reviewer's comments and naming the state precisely after the merge.
Learning outcome. After this unit the reader can follow one complete example of implementation from request to merge; tell evidence that something works from evidence that it is valuable to users; set the boundary of a slice and write a short brief for an agent; assess checks across positive, negative and integration scenarios; and explain exactly what has been approved, what remains unknown and whether the changes are already available to users.
Prerequisites. Earlier parts of the course supplied the ingredients of this process: defining the problem, context and sources of truth, technical design, acceptance criteria, agent loops, working with branches, reviewing changes and orchestration. Vertical Slices has already shown slices using the examples of viewing and cancelling a booking. The unit on agent task contracts covers the agent's task contract in detail; here it is needed only as a concise working brief.
All the names of people and systems and all the figures in the teaching cases below are invented. This is not a report on code that was run or on a production system. The one real public example, from Django, is marked separately and described only within the limits of verified facts.
From a user's intent to a decision about the work
Imagine a hypothetical booking service. A customer has a confirmed booking but wants to move it to another free time without contacting support. The first phrase, "add booking rescheduling", is not yet a ready task. It does not say who may reschedule a booking, which hours are allowed, what to do when two people race for the same free slot, or what the customer will see when the slot they want has already been taken.
First the author states the person's intent and the expected change. For example: "A customer with a confirmed booking can choose an available time and see that it is their booking that has been moved." This is a hypothesis about improving the experience and perhaps reducing support requests. A finished screen, a request to the server and even a successful code check do not prove that customers will notice the feature, understand it or want to use it, or that support costs will actually fall.
This distinction is consistent with Marty Cagan's framework of product risks: value to the customer, usability, feasibility and viability for the business are separate risks (The Four Big Risks). Code and automated checks provide evidence mainly about feasibility; on their own they test neither demand nor business economics. In his article on product discovery, Cagan describes researching the problem and testing assumptions with users, without requiring every team to follow the same order of steps (Product Discovery, an author's article; we do not claim to have read the full book Inspired).
Before implementation starts, collect links to the authoritative artefacts and note briefly what follows from each:
| Artefact | What the author needs to establish |
|---|---|
| The request or problem description | Who has the problem and which behaviour should change |
| Clarifications and the product owner's decisions | The rescheduling deadline policy, the booking type, access limits and open questions |
| Acceptance criteria | The observable result for success, refusal and recovery |
| Current architecture decisions | Which storage, application programming interface (API), authorisation and components are already sources of truth |
| Data schema and API contract | Which identifiers and time fields are authoritative; what the client and the server expect |
| Related tasks and previous implementation | What is already finished and where the history should not be duplicated |
An API, in this sense, is the agreed way in which components exchange requests and responses. There is no need to copy entire earlier discussions into the new work description: name the decision you need, link to its source and record only the context this change requires. If sources contradict one another, the agent must not pick the more convenient one at random; the author has to find the owner of the decision.
The slice boundary: small enough, but still correct
For the first version, let us set the goal: a customer moves one future confirmed booking to another free time. The minimal slice passes through the data, the server-side logic, the API and the user interface (UI), if those are exactly the components the current architecture needs.
In scope: load the customer's own booking; show the permitted free times; accept the choice; on the server, check identity, the right to make the change, the booking's status and the availability of the time; save the rescheduling as one consistent operation; show a truthful result; explain a conflict and leave a path to recovery.
Out of scope: creating a new booking, changing payment, calendar synchronisation, automatic notification of third parties, an admin editor and rebuilding the whole booking system. If a notification requirement is approved later, it will be separate, related work. Reducing scope can postpone an animation or an extra notification channel, but it cannot remove the owner check, saving a consistent state or the error message. In the Shape Up approach, "fixed time, variable scope" is a way to agree on the boundaries of a bet, not permission to leave a critical property incomplete (Shape Up: Set Boundaries). In the Shape Up chapter on getting one piece done, Ryan Singer describes integrating the interface and the server side early as a way to get working behaviour that can be checked; this is a method from Basecamp's particular practice, not a universal rule for the size of a pull request (PR) (Shape Up: Get One Piece Done; sources checked 24 September 2026).
A hypothetical scenario contract might read:
- An authorised customer opens their own future confirmed booking.
- The service shows the options available for this resource and time period.
- The customer chooses one option and submits it for their booking.
- The server checks the right, the current status and the availability of the option again, and then saves the rescheduling consistently.
- The interface reports completion only after the saved state has been confirmed.
- If the time is no longer available, the service keeps the previous booking and explains how to choose another time.
Acceptance criteria describe behaviour, not the internal implementation someone would like: "another customer cannot change this booking" is a criterion; "add another service" is a technical proposal until there are grounds to accept it. The criteria must cover the policy's time limit, if there is one, such as a ban on changes after the appointment has started. Do not invent that limit in code if the owner of the product rule has not confirmed it.
Preconditions and the working brief
Before changing any files, check the actual state of the repository copy. Create a separate working branch from the current base revision, record its commit, look at the status of uncommitted changes, make sure it is the repository you expect, and establish whether the necessary dependencies and settings are in place. If the working tree already contains someone else's or uncommitted changes, first find out where they came from; do not wipe or stash them in order to "start clean". Do not test the logic on production data or live accounts.
A Git branch is a separate pointer to the tip of the commit history; creating one does not, by itself, create a new commit. The git diff command lets you compare a change with the index, the working tree or a chosen base. This gives a clear boundary for commit history and for review, but the branch itself does not separate uncommitted files in a shared working tree and does not prove that the changes are correct (git switch, git diff, checked 26 September 2026). The reviewer needs to know the exact base revision: otherwise the diff can hide an existing difference or include unrelated work.
A concise brief for the implementing agent should state the goal, the sources, the boundaries, the evidence required and the constraints. For example:
Goal: allow the owner of a confirmed future booking to move it to an available time. Sources: the task and the criteria at the linked locations; the current
Booking APIcontract; the rule "changes are allowed until the booking starts", approved by the product owner. In scope: server-side owner authorisation, a repeated availability check, atomic saving, and loading/error/success states in the existing screen. Out of scope: payment, notifications, calendar synchronisation and refactoring of other scenarios. Evidence: a positive check for the owner, a negative check for someone else's booking, a taken-slot conflict, the boundary time, a regression check for viewing a booking and an integrated scenario on the agreed contract. Stop: if the rule or the contract contradicts the codebase, stop and name the missing decision; do not widen permissions, do not change the external API on your own and do not act outside the permitted working environment.
The brief is deliberately short. The full structure of the contract, permissions, preconditions and the agent's report is the subject of Agent Task Contracts. OpenAI's general guidance on Codex emphasises a specific task, relevant paths and context; the /review command can produce prioritised findings without changing the working tree. In Claude Code, plan mode does not edit files until you confirm, and the /diff command shows the current Git changes. These are product capabilities that depend on the environment and settings; an agent's report does not approve a PR and does not replace the repository's checks. Details checked 26 September 2026: OpenAI: how OpenAI uses Codex, code review in Codex, Claude Code common workflows, Claude Code interactive mode.
Data consistency and helpful feedback
Rescheduling is not just a change of label on a screen. Between the moment the customer sees a free time and the moment it is saved, another customer can take that same time. The server must check the state again when it writes. A transaction lets a group of changes be saved entirely or not at all; in PostgreSQL, the row lock SELECT … FOR UPDATE holds the selected row against concurrent changes until the transaction finishes. But locking the booking itself does not reserve an empty time interval. Overlapping intervals need a separate integrity constraint or a suitable concurrency mechanism at the storage level. For range types, the PostgreSQL documentation shows an exclusion constraint that can prohibit overlapping intervals for the same resource. If such a constraint combines a range-overlap check with equality on a plain resource identifier in a GiST index, the btree_gist extension may be needed. A transaction does not, by itself, create a business rule (PostgreSQL transactions, row-level locks, range types and constraints, btree_gist). The exact model of statuses and availability is set by the application.
The short SQL (Structured Query Language) fragment below shows only an important difference in the search condition. It is not a ready implementation: the syntax, the data model and the concurrency strategy have to match the real system.
-- Initial unsafe direction: the booking identifier alone is not enough.
SELECT id, owner_id, slot_id, status
FROM bookings
WHERE id = :booking_id
FOR UPDATE;
-- Needed: a filter on the owner, as determined by the server from the authenticated session.
SELECT id, owner_id, slot_id, status
FROM bookings
WHERE id = :booking_id
AND owner_id = :authenticated_user_id
AND status = 'confirmed'
FOR UPDATE;
The client must not set authenticated_user_id through an arbitrary request parameter: the server takes it from the verified login context. Then the server checks the target time and saves the change in a transaction. If the rule against duplicate time intervals is enforced by a database constraint, a concurrent attempt should be rejected by the storage layer, and the server turns that refusal into a clear API response. For example, the code 409 Conflict in the Hypertext Transfer Protocol (HTTP) can mean a conflict with the current state of the resource; applying it specifically to a taken time slot is a decision of the API contract, not a requirement of the HTTP standard, RFC 9110 (status 409). Likewise, the PUT method is appropriate only if the contract really describes replacing the state of the booking resource; the HTTP standard does not define the booking domain itself (the PUT method).
In the interface, a person needs to understand the next step and whether the system has already finished the action. Usability is not about the minimum number of clicks: even a short path is bad if the result is unclear or a failure is hidden. This scenario needs at least the following states:
| State | What the customer sees | What the system must do |
|---|---|---|
| Loading | "Checking available times…" | Not allow an unknown option to be confirmed prematurely |
| No options | "There are no free times for this period" and a clear way out | Keep the current booking |
| Error, or the time is already taken | An explanation without technical jargon; an offer to refresh the options | Not report success and not lose the previous booking |
| Success | The new time, matching the saved state | Show success only after the server confirms it |
| Recovery | A "try again" action or a return to the choice | Repeat the read without duplicating the unsafe operation |
Short, timely explanations and an obvious next step are consistent with Steve Krug's advice on clear pages and on watching how people go through a scenario. Here it is a guide for the wording of the states, not evidence that a particular interface is easy to use; that has to be tested with users (excerpt from Don't Make Me Think, its tenth chapter, checked 24 September 2026).
Evidence for acceptance and re-checking
The names of checks are useful only together with the result, the revision and the link to a criterion. For the invented example, a suitable set looks like this:
| Criterion | Check | Result required |
|---|---|---|
| The owner moves a confirmed booking to a free time | Positive check of the service and of the end-to-end scenario | The response and a repeat read show the new time on exactly this booking |
| Another customer cannot change someone else's booking, even with its identifier | A negative request from a different session | Refusal without revealing or changing the other person's data |
| The time was taken between viewing and saving | A concurrent or conflict scenario | The conflict is returned to the customer; the old booking remains valid |
| A change after the forbidden time limit | A boundary check of the policy | The server rejects the rescheduling regardless of the interface state |
| Viewing one's own booking still works | A regression check | Existing fields and the response format are not broken |
| The browser and the server use the same contract | An integration check | The identifier, the time and the error states match the current schema |
During implementation, name the specific checks, the actual command and its exit code. For example, the report should say: "At revision abc123 the authorisation check rejected someone else's booking_id; a repeat read confirmed that the owner and the time had not changed." If a command was not run, say so. The illustrative output below is only a teaching example of how to tie a result concisely to a criterion; it does not describe an actual run:
Illustrative run for the teaching case (not executed on a real system)
owner + free time PASS — new time returned, repeat read consistent
different owner PASS — no change, other person's fields not returned
time already taken PASS — previous booking kept, conflict shown
after the time limit PASS — server rejected the rescheduling
booking view PASS — previous scenario not broken
client/server integration PASS — both sides read the same contract
An independent review should compare the change with the original intent, check every criterion, read the negative path and look for any weakening of a test or an access rule. An agent's review of a specific diff is a useful additional signal; the repository maintainer's decision and the required statuses are different things. On GitHub, approval rules and required checks depend on how the target branch is configured. A status check can be skipped, and a "successful" mark does not prove that the required check actually existed. So record what was really configured and run, rather than drawing a conclusion from the colour of an indicator alone (GitHub: pull request reviews, status checks, checked 26 September 2026).
Three teaching cases within one slice
Below are three complete teaching cases. All booking names, data, run results and dialogue are invented. They show the sequence of decisions, not real agent runs.
Case 1: rescheduling one's own booking, from request to review
A customer, Olena, has a confirmed booking for Thursday and wants to move it to Friday. The ticket initially says only "make it possible to reschedule a booking". The author clarifies the owner, the status and the time limit, and links to the booking schema and the agreed API contract. Under the policy of this invented system, a future confirmed booking may be rescheduled until the appointment starts. Prompts to change the payment and notifications to the customer are excluded from the first version.
The author checks the branch and that the working tree is clean, identifies the data sources and gives the agent a brief with criteria. The agent finds the existing booking screen, the server-side update method and the test infrastructure. The plan shows that the necessary negative test for someone else's booking does not exist yet. The first diff adds the choice of a new time, but the server-side query looks the booking up by its identifier only. In the happy path, the interface shows success.
The review finds two separate gaps: the owner condition on the server, and the race between showing a free time and writing it. The change is not accepted just because the positive screen works. The agent adds the owner filter, a repeat check on the server and conflict handling backed by a storage constraint. The author checks the negative test, the concurrent case, the old viewing scenario and the end-to-end contract on the new revision. The interface shows success only after the response confirming the saved state, and on a conflict it keeps the previous booking and offers to choose another time.
The PR description contains the goal, links to the task and the contract, what is included and excluded, the identifier of the last verified revision, the checks that were run with their actual results, and the limitations: the new feature has not yet been tested with real users. After review and once the repository's requirements are met, the maintainer merges the PR. That means the changes have reached the target branch. It is not yet a claim that users already have the feature.
Case 2: the reviewer finds a missing owner check
During the first review, the reviewer sees a query to bookings by booking_id with no link to the authenticated user. On positive data this looks correct: Olena opens her own booking and sees the available times. But another customer can substitute Olena's booking identifier into the same request. If the server trusts the identifier alone, the request can reveal data or change another person's booking. This is an example of Broken Object Level Authorization (BOLA): every endpoint that accepts an object identifier and acts on it must check the right to that specific object (OWASP (Open Worldwide Application Security Project) API Security: API1:2023).
The reviewer requests a change: take the user from the verified session context, include them in the server-side access condition, add a negative check with a different user and confirm that nothing changed after the refusal. The agent fixes the query and the checks. The reviewer does not assume the fix worked: they read the new diff and the result on the new revision, including evidence that the other person's booking did not change. Only then do they approve the changes. An old check result cannot automatically be attributed to a new commit.
Case 3: the API contract changed before the merge
The day before the merge, the team that maintains the shared contract renames the request field slotId to newSlotId. This is a teaching scenario; we assume the contract has not yet been published to clients. The author does not ask the agent to add an arbitrary field for compatibility, and does not ignore the change. They check the source of the decision, clarify which revision is authoritative, update the schema and bring the client, the server and the integration check into line with the new name. Then the team re-runs at least the contract, successful-rescheduling, conflict and authorisation checks on the changed revision.
This is not scope creep: the change is needed for the same behaviour under the current contract. If, however, the old contract is already available to external consumers, the author halts the merge and hands the decision about compatibility, a transition period or a new API version to its owner. Such a policy can change scope and risk; the agent must not quietly ship a breaking change (an incompatible change to the contract) disguised as a local edit. The PR updates the list of dependent checks and states that the contract changed. The reviewer checks not only the schema lines but that every consumer matches and what the actual integration result is.
How to read a real pull request
Vertical Slices already reconciled the scope of changes and the tests in a real FastAPI pull request; here the focus is on what the reviewer's comments say and on the difference between approval and merge.
In the real Django pull request #21213, the fix is for loading a fixture from a path that contains a dot. Django ticket #37081 describes a reproducible problem: a directory path such as fix.v1 was mistakenly parsed as a file suffix. The PR's files show a change to the loaddata command and checks for paths with a dot, compressed files, parent directories and a leading dot. Earlier in the discussion, someone proposed parsing the path with PurePath; in a comment on 21 September another reviewer asked about compound suffixes, and the author explained the difference between .stem and the current way of splitting suffixes with a concrete example. A later review contains an approval. As of 26 September 2026 the PR was still open despite the approval, so it should not be described as already merged or released.
Verified direct links: Django ticket #37081, PR #21213, files changed, the PurePath comment, the question about compound suffixes, the author's explanation, the approval. The example shows how a requirement, a counterexample, a regression check, the author's response and an approval coexist in one review. It does not establish a universal Django process for all changes, and it does not prove that a similar process automatically produces a correct result in your repository.
Merge, deployment and availability to users
A pull request on GitHub brings together the description, comments, reviews, commits, the comparison of changes and the configured checks. A reviewer can leave a comment, approve the change or request changes. Which approvals and checks block a merge is decided by the rules of the target branch. That is a setting of the repository's process, not a property of every pull request (GitHub: about pull requests, reviewing proposed changes, checked 24 September 2026).
A merge adds the changes to the target branch. A deployment delivers a specific version to a particular environment. A release makes a feature available to the intended group of users; that can happen through a versioned release, a configuration toggle, a gradual rollout or another controlled process. In some teams a merge automatically triggers a deployment; that is a link the team has configured, not a promise from GitHub. A deployment can also have its own environment rules and approvals (GitHub: deploying code, deployment environments). Vertical Slices also shows the difference between merging and releasing; the operational work of releasing is covered in more depth in continuous integration, continuous delivery and deployment, environments, deployment strategies, rollback and recovery and release management.
Before you report "done", name the state precisely:
- the code is ready and verified at a specific revision;
- the PR is approved but is waiting for a required check or for the merge;
- the changes are merged into a named branch;
- the build is deployed to a named environment;
- the feature is open to a named group of users;
- there are product assumptions that code has not verified.
After the merge, update the task and the documentation so that the next participant knows the exact revision, the results, the known limitations and who is responsible next. Do not mark a feature as released if only the merge has been confirmed. The owner of the product risk has to decide whether there is enough evidence to show the feature to real users, especially if user testing, outcome measurement or a controlled launch has not yet happened.
Summary of evidence and uncertainty
For the hypothetical booking rescheduling, the overall evidence consists of connected parts: an agreed requirement and boundary, a server-side owner check, protection against time conflicts, a clear interface state, positive and negative checks, a review of the current diff and a precise status after the merge. No single green check, agent response or reviewer approval is evidence of all these properties at once.
In the teaching example, what would be confirmed is that the implementation at the named revision meets the listed criteria in the simulated scenarios. What remains unconfirmed is whether customers want to use rescheduling, whether support requests actually fall, whether the wording is clear to different groups of people, and whether the operational process is ready to support the launch. Risks related to other booking statuses, time zones, external contracts and recovery after a failure should be named explicitly if they lie outside the verified boundary.
Sources and further reading
Each entry notes what the source supports and where the claim stops.
- Git: git switch and git diff. Isolation by branch and comparison of changes.
- GitHub: about pull requests, reviewing proposed changes, pull request reviews, status checks, deploying code, deployment environments. The pull request process depends on the repository's settings.
- OpenAI: how OpenAI uses Codex, code review. Reference on current product capabilities; not a guarantee of correctness or a replacement for the target branch's required rules.
- Anthropic: Claude Code common workflows and interactive mode. Planning and change review as described by the vendor; actual access modes depend on configuration.
- PostgreSQL: transactions, row-level locks, constraints on ranges,
btree_gist. The integrity mechanisms the invented example relies on; the booking domain rule belongs to the application. - HTTP: RFC 9110, PUT, RFC 9110, 409 Conflict. The standard describes the method and the response code; how they map onto a particular API is a contract decision.
- OWASP: API1:2023 Broken Object Level Authorization. Authorisation must be checked for the object whose identifier arrived in the request.
- Marty Cagan: The Four Big Risks and Product Discovery. The author's articles on product risks and exploring the problem; not the full book Inspired.
- Ryan Singer: Set Boundaries and Get One Piece Done. The open text of Shape Up on the boundaries of a bet and early integration; not a universal team standard.
- Steve Krug: excerpt from Don't Make Me Think, its tenth chapter. Usability-testing advice from an excerpt of the first edition, not the full Don't Make Me Think, Revisited.
- Real example: Django ticket #37081, PR #21213 and the links to specific files, comments and the approval in How to read a real pull request. At the time of access the PR was open with an approved review; this is not evidence of a merge.