Vasu Patel logoVasu Patel
← From Idea to Production: the SDLC
All chapters in this track
  1. 01Chapter 1: Why the SDLC Matters
  2. 02Chapter 2: An Honest Comparison of SDLC Models: Waterfall, Iterative, Agile/Scrum, Kanban, Lean, Spiral, DevOps
  3. 03Chapter 3: Choosing and Adapting a Model for Team Size, Domain, and Risk Tolerance
  4. 04Chapter 4: Requirements Gathering and Analysis
  5. 05Chapter 5: The Design Phase and Its Connection to HLD/LLD
  6. 06Chapter 6: Implementation Practices That Keep a Project Healthy
  7. 07Chapter 7: Testing Strategy Across the Pyramid
  8. 08Chapter 8: Documentation Across the Lifecycle: Specs, ADRs, Runbooks
  9. 09Chapter 9: Release and Deployment: CI/CD, Versioning, Blue-Green and Canary Releases, Feature Flags
  10. 10Chapter 10: Operations and Maintenance: On-Call, Monitoring, Incident Response
  11. 11Chapter 11: Measuring Delivery Health: Cycle Time, Deployment Frequency, Change Failure Rate, MTTR
  12. 12Chapter 12: Case Study: The SDLC in a Five-Person Startup
  13. 13Chapter 13: Case Study: The SDLC in a Large Enterprise Team
  14. 14Chapter 14: Worked Example: Choosing a Process for a New Team
  15. 15Chapter 15: Common Interview Questions About the SDLC

Chapter 6 of 15

Chapter 6: Implementation Practices That Keep a Project Healthy

Why this matters

Implementation is where most of an SDLC's actual engineering time is spent, and it's also where a project's health silently erodes or is actively maintained — a project can have excellent requirements and design and still degrade badly during implementation through poor branching practices, unmanaged technical debt, or scope creep that nobody explicitly decided to accept.

Branching strategy: trunk-based development vs. long-lived feature branches

[BEGINNER] Long-lived feature branches (a branch that stays open and diverges from the main branch for days or weeks while a feature is built) risk a specific, real problem: the longer a branch diverges, the more likely it accumulates painful merge conflicts, and the less other engineers' work is tested together with it until a large, risky merge finally happens.

main:    A---B---C---D---E---F---G  (other work keeps landing here)
              \
feature:       C1---C2---C3---C4---C5   (diverges for weeks, then merges
                                          all at once -- a large, risky
                                          integration event)

Trunk-based development favors small, frequent merges to the main branch — often daily — using techniques like feature flags (Chapter 9) to hide incomplete functionality from users even though the code is merged and integrated continuously:

main:    A---B---C---D---E---F---G---H---I  (small pieces of the feature
                                              merge in continuously, hidden
                                              behind a feature flag until
                                              complete, per Chapter 9)

[SENIOR INSIGHT] The real trade-off: trunk-based development requires more discipline (feature flags, ensuring every small merge keeps the main branch in a working state) but avoids the large, risky integration events long-lived branches eventually force — this connects directly to the companion Coding Standards book's Chapter 8 (small, atomic commits/PRs) and the companion Code Reviews book's Chapter 2 (small, reviewable PRs): trunk-based development is essentially that same "keep changes small and frequently integrated" principle, applied at the branching-strategy level.

Managing scope creep during implementation

[BEGINNER] Scope creep is the gradual, often unnoticed expansion of a feature's scope beyond what was originally designed and agreed upon — "while I'm in here, I might as well also fix/add X" — which individually seems reasonable but collectively can turn a well-scoped, well-designed feature into an unplanned, unreviewed sprawl.

Original scope (per Chapter 5's design): add a "reorder" button.

Scope creep, accumulated during implementation without anyone deciding
to expand scope: also refactoring the entire CartService "while I'm in
here," also adding a new discount-stacking feature that seemed related,
also changing the button styling for "consistency" -- none of these were
part of the reviewed design, and the resulting PR is now three times
larger and touches far more than what was actually planned and reviewed.

The discipline: when a genuinely good idea for additional scope surfaces during implementation, capture it as a separate, explicitly-scoped follow-up (a new ticket) rather than folding it into the current work silently — this keeps the current PR reviewable (companion Code Reviews book, Chapter 2) and ensures the additional idea gets its own deliberate design/prioritization consideration rather than riding along unreviewed.

Managing technical debt deliberately, not by accident

[SENIOR INSIGHT] Technical debt — a shortcut taken now that will cost more to properly address later — is sometimes a legitimate, deliberate trade-off (ship a simpler version now to meet a real deadline, with an explicit plan to revisit) and sometimes an unmanaged, accidental accumulation nobody decided to accept. The distinction matters enormously: deliberate technical debt, taken consciously with a plan to address it, is a normal, healthy part of shipping software under real constraints; accidental technical debt, accumulated through scope creep, skipped design, or "we'll fix it later" promises that are never tracked or revisited, silently degrades a codebase's health over time with no corresponding record of what was traded away or why.

## A deliberate technical debt decision, tracked explicitly
We're shipping the reorder feature without handling the case where MORE
THAN 50 items are reordered at once, since our current usage data shows
no customer has ever had more than 15 items in a single order. Tracked
in TICKET-1204 to revisit if usage patterns change. This is a conscious,
documented trade-off, not an oversight.

Common mistakes

  1. Using long-lived feature branches by default, accumulating merge conflict risk and delaying integration testing until a large, risky merge event, rather than favoring small, frequent, trunk-based integration.
  2. Allowing scope creep to accumulate silently during implementation, turning a well-scoped, well-reviewed design into an unplanned, unreviewed sprawl — capture additional ideas as separate follow-up tickets instead.
  3. Accumulating technical debt accidentally, with no record of what was traded away or why, versus taking it on deliberately with an explicit, tracked plan to revisit — the difference between healthy, managed debt and silent codebase degradation.
  4. Not distinguishing "while I'm here, I'll also fix this small thing" (often fine, especially for a tiny, directly-related cleanup) from genuine scope expansion (a new feature or a large refactor) — the line matters, and treating every "also" as automatically fine or automatically forbidden misses real nuance.

Checklist: healthy implementation practices

  1. Favor small, frequent merges to the main branch (trunk-based development) over long-lived feature branches, using feature flags to hide incomplete functionality where needed.
  2. When additional scope surfaces during implementation, capture it as a separate follow-up ticket rather than silently folding it into the current work.
  3. When taking on technical debt, document the decision explicitly — what's being traded away, why, and under what conditions it should be revisited — rather than letting it accumulate as an unrecorded, accidental cost.
  4. Periodically review accumulated technical debt as a team, distinguishing deliberate, tracked trade-offs from accidental accumulation that needs addressing.

Discussion / interview questions

  1. "What's the difference between trunk-based development and long-lived feature branches, and what's the trade-off?" Strong answer: Trunk-based development favors small, frequent merges to the main branch (often using feature flags to hide incomplete work), avoiding large, risky, late integration events; long-lived feature branches diverge for extended periods, accumulating merge conflict risk and delaying integration testing — trunk-based requires more discipline but avoids the large, risky merge trunk-based approaches are specifically designed to prevent.

  2. "What is scope creep, and how would you manage it during implementation?" Strong answer: The gradual, often unnoticed expansion of a feature's scope beyond what was designed and agreed upon; managed by capturing additional ideas as separate, explicitly-scoped follow-up tickets rather than silently folding them into the current work, keeping the current PR reviewable and giving the new idea its own deliberate consideration.

  3. "Is taking on technical debt always a bad practice?" Strong answer: No — deliberate technical debt, taken consciously with an explicit, tracked plan to revisit, is a normal, healthy part of shipping under real constraints; the problem is accidental, unmanaged technical debt accumulated with no record of what was traded away or why, which silently degrades a codebase over time.

  4. "How would you decide whether a 'while I'm in here' addition during implementation is acceptable, or scope creep to avoid?" Strong answer: A tiny, directly-related cleanup that doesn't meaningfully expand review scope is often fine; a new feature, a large refactor, or anything that wasn't part of the reviewed design and would substantially grow the PR should be captured as a separate follow-up instead — the distinguishing question is whether it changes what a reviewer needs to evaluate beyond the original, agreed scope.

Chapter summary / cheat sheet

  • Trunk-based development (small, frequent merges, feature flags for incomplete work) avoids the large, risky integration events long-lived feature branches eventually force.
  • Scope creep — silent, unplanned expansion during implementation — should be captured as separate follow-up tickets, not folded into the current work unreviewed.
  • Technical debt taken on deliberately, with an explicit, tracked plan to revisit, is healthy and normal; accidental, unrecorded technical debt silently degrades a codebase over time.
  • These practices connect directly to the companion Coding Standards and Code Reviews books' "keep changes small and reviewable" theme, applied specifically to branching strategy and scope management during implementation.