Implement a Feature End to End
Activated Cloud✓ Officialactivated/implement-feature-end-to-end
Free · MIT
About
Takes a feature or multi-file change from request to a verified, committed result: confirm the ask, get a baseline, plan with a todo list, read before every edit, find every caller before changing an interface, build in small tested slices, run the project's own tests, linters and type checks, exercise the feature for real, review your own diff and report with evidence. Use for any change spanning several files or steps. Not for a one-file tweak (use make-surgical-change) or finding a bug's cause (use debug-root-cause).
Documentation
Implement a Feature End to End
This is the full loop a senior engineer runs for a real change: understand it, build it in small verified steps, prove it works, and hand back something a reviewer can trust. The standard is simple and strict: nothing is called done until you have run the project's own checks and seen them pass, every edit was made to a file you had just read, and the diff contains the change and nothing else.
When to use
- "Build X", "add Y to the app", "implement this ticket", "wire up the new endpoint and the page".
- Any change that touches several files, needs new tests, or has more than two steps.
- Executing a plan you or a teammate wrote.
What you need
- The request, with acceptance criteria if they exist. If not, you will write them in step 1.
- The repository with write access: the owner's GitHub or GitLab connected app (Connections page) or a git credential on your computer. If neither is there, ask with
clarify, or work on an uploaded copy and hand back a patch. - The project's commands for install, test, lint, format, type check and build. If you do not know them, find them first: CI config, then task runners, then docs.
- The owner's standing preferences from
memory(branch naming, whether you may push, whether to fix pre-existing failures).
Method
1. Confirm the ask
- Restate the goal in one sentence and list acceptance criteria as observable results. Write what is out of scope.
- If an ambiguity changes what you would build, ask with
clarifyand offer two or three concrete options with your recommendation. Otherwise state your assumption in the report and proceed. - Check
session_searchfor earlier conversations about this feature.
2. Orient and baseline
git status --short && git branch --show-current && git log --oneline -5
<test command>; echo "exit=$?"
- If the tree has changes you did not make, stop and ask before touching anything.
- Run the full test suite, linter and type checker once before changing anything. Record pass and fail counts and every pre-existing failure by name. This is your baseline; without it you cannot tell your breakage from old breakage.
3. Plan with a todo list
- Break the work into vertical slices: each slice is one behaviour working end to end, small enough to finish and verify in one sitting.
- Create the list with
todo. Add three closing items to every list: "run all checks against baseline", "exercise the feature for real", "review own diff". - Exactly one item is
in_progressat a time. Mark an itemcompletedonly after its verification passed, never on intent. If an approach fails, cancel the item and add a revised one. - For large or risky work, write a proper plan first (blast radius, ordered tasks, rollback) and get the owner's nod.
4. Branch
git fetch origin && git switch -c feat/<short-slug> origin/<default-branch>
Follow the repo's branch naming. Do not commit straight to the default branch of a shared repo unless the owner's workflow says so.
5. Build each slice
For every slice, in this order:
- Read before you write.
read_fileevery file you will change: the whole function you are editing, its imports, and its neighbours. Re-read a file if anything may have changed it since you last read it (a formatter, a teammate, a subagent, your own earlier edit). Neverpatchfrom memory. - Find every caller before changing an interface. Before you rename or change the signature of a function, method, class, exported constant, route, config key, environment variable, CLI flag, event name or DB column, run
search_filesfor the name with word boundaries and for its string forms across code, tests, templates, YAML, SQL and docs. List the hits. Update all of them in the same change, or keep the old interface working (a default parameter, an alias) and say so. - Copy the local pattern. Find an existing example of the same kind of thing in this codebase (another endpoint, another model, another component) and match its structure, naming, error handling, logging and test style. The codebase's conventions beat your preferences.
- Write the test first when you can. Write a test for the slice's behaviour, run it, and watch it fail for the right reason (an assertion about the missing behaviour, not an import error).
- Make the smallest edit that does the job. Use
patchwith anold_stringunique enough to hit the right place, and read the diff it returns: fuzzy matching can land an edit somewhere you did not intend. Usewrite_fileonly for new files. - Run the narrowest check, then widen. The new test, then the test file, then the package's tests. Check the exit code of every command, not just the last lines of output.
- Commit the slice. Stage explicit paths, never
git add -Ablindly. One logical change per commit with a message that says why.git add src/coupons/policy.py tests/coupons/test_policy.py git diff --cached --stat git commit -m "feat(coupons): reject expired coupons at checkout"
6. Delegate independent slices
When two or more slices share no files and no interfaces, hand them to subagents with delegate_task (a tasks list runs them in parallel). Each brief must stand alone: the subagent knows nothing of your conversation. Use references/delegation-brief.md. When results come back, do not trust "done": read their diff, run the checks yourself, and fix or send back anything that fails.
7. Integrate and run every check
Run the full test suite, linter, formatter check, type checker and build. Compare with your baseline: there must be no new failures. If something fails:
- Fix the cause. Do not delete, skip or loosen a test to get green, and do not add
# type: ignore,@ts-ignore,eslint-disableor#[allow(...)]without a one-line reason the reviewer will accept. - After three failed attempts at the same fix, stop guessing: reproduce it in isolation and find the root cause, or ask.
- Pre-existing failures: list them in the report and offer to fix them. Fix them in this change only if the owner has said they want that.
8. Exercise it for real
Tests prove what they test. Also run the thing:
- API: start the server in the background (
terminal(background=true)), call the endpoint withcurl -sS -w '\n%{http_code}\n'and check status and body. - CLI: run the command with realistic input and with bad input.
- UI: open the page with
browser_navigate, look withbrowser_snapshotorbrowser_vision, click through the flow, and check the browser console and server log for errors. - Background jobs: trigger one and read its log line.
9. Review your own diff
git diff origin/<default-branch>...HEAD --stat
git diff origin/<default-branch>...HEAD
Read every line as a reviewer would. Remove debug prints, commented-out code, stray TODOs, unrelated formatting churn and accidental files. Look for secrets, missing error handling at boundaries (I/O, network, user input), missing tests for new branches, and names that do not match the codebase.
10. Stop and ask before anything destructive or external
Ask with clarify before you: drop, truncate or rewrite data; run a migration against anything but a local or throwaway database; delete branches, tags or files outside your change; force-push or rewrite pushed history; deploy to production; publish a package; add a paid service or dependency; change a public API contract; rotate or touch credentials.
11. Report
Push and open a pull request only if the owner asked for it or their workflow says so. Then hand over using references/handover-template.md: what changed, how you verified it (commands and results), what you did not verify and why, risks, and next steps.
Output
A branch with small, logical commits, and a handover in the shape of references/handover-template.md. Every claim in it is backed by a command you ran and its result. If the owner is watching, put the summary and the check results on a show_card.
Checks before you finish
- Full test suite, linter, formatter check, type checker and build have been run after your last edit, and none has a failure that is not in the baseline.
- Every acceptance criterion has evidence next to it (a test name, a command output, a screenshot).
- Every caller of every changed interface was updated or deliberately kept compatible.
git statusis clean apart from intended changes; the diff has no debug code, secrets or unrelated edits.- The
todolist has no item marked completed that was not verified.
Pitfalls
- Claiming success without running the checks. "Should work" is not a status. Run it, read the exit code, then say what it showed.
- Editing from memory. Patching a file you read twenty steps ago overwrites changes or misses context. Read it again.
- Changing a signature and fixing only the callers you remember. Search for every reference, including strings and other packages.
- One giant commit. Small commits make review possible and make reverting one mistake cheap.
- Gold-plating. Do what was asked. Note other improvements for later instead of folding them in.
- Silencing failures. A skipped test or an ignore comment hides the bug from everyone, including the owner.
- Trusting a subagent's summary. Verify its diff and run its checks yourself.
- Drifting from the codebase's style. A correct change written in a foreign style still costs the reviewer time and invites churn.
Versions
Listed from the source repository.
Reviews
No reviews yet. Be the first.
