agentleFS
JordanCoinJordanCoin/codingskills/skills/yagni/SKILL.md

yagni

Skill10 starsChanged 9 months agoMITView on GitHub

When writing or reviewing code to prevent over-engineering and speculative features. Use when the user says "is this over-engineered," "do we need this," "should I add," "future-proof," or "just in case." For simplicity concerns, see kiss. For abstraction design, see solid.

6 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

9 rules. 0 are common, 8 are distinctive, and 1 is very specific to this project.

  • 0

    Common

    Most of the 6 edited versions we read keep these.

  • 8

    Distinctive

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  • could be automatic: a setting could enforce it
  1. Very specific:

    If .agents/stack-context.md exists, read it first.

    line 12
  2. Distinctive:

    Do not build for hypothetical future requirements.

    line 16
  3. Distinctive:

    Solve the problem in front of you: If you have one use case, write code for one use case.

    line 26
  4. Distinctive:

    Delete speculative code paths: If a feature flag has never been toggled, a configuration option has never been changed, or a parameter has …

    line 28
  5. Distinctive:

    Prototype when uncertain: If you aren't sure whether something will be needed, spike it in a branch.

    line 30
  6. Distinctive:

    YAGNI does not mean avoid extensibility at zero cost: If making code extensible costs nothing (e.g., using a map instead of a switch …

    line 74
  7. Distinctive:

    kiss: When the issue is complexity rather than speculation

    line 87
  8. Distinctive:

    solid: When designing abstractions that are justified

    line 88
  9. Distinctive:

    dry: When deciding whether to extract a pattern (YAGNI says wait for 3 occurrences)

    line 89

“Common” is measured: kept by at least 6 in 10 of the 6 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

YAGNI — You Aren't Gonna Need It

Before Applying

If .agents/stack-context.md exists, read it first. Apply this principle using idiomatic patterns for the detected stack. For framework-specific details, use context7 MCP or web search — don't guess.

Principle

Do not build for hypothetical future requirements. Build what is needed now, and refactor when actual requirements emerge.

Why This Matters in Production

Speculative code is the #1 source of accidental complexity. Every abstraction, configuration option, or extension point you add "just in case" has a real cost: it must be understood, tested, maintained, and debugged. Unused code paths are the most dangerous — they rot silently, give false confidence in test coverage, and create surface area for bugs.

Premature generalization is worse than duplication. Duplication is obvious and easy to fix later. A wrong abstraction is painful to undo because other code grows to depend on it.

Rules

  1. Solve the problem in front of you. If you have one use case, write code for one use case. Not two. Not "what if later."
  2. Three strikes, then abstract. The first time you write something, just write it. The second time, note the duplication. The third time, extract the pattern — now you have enough data to design the right abstraction.
  3. Delete speculative code paths. If a feature flag has never been toggled, a configuration option has never been changed, or a parameter has never been passed anything other than the default — remove it.
  4. Don't build plugin systems for one plugin. Interfaces, registries, and extension points are justified only when you have multiple concrete implementations today.
  5. Prototype when uncertain. If you aren't sure whether something will be needed, spike it in a branch. Don't merge speculative infrastructure into main.

Anti-Patterns

  • Adding parameters "for flexibility" that only ever receive one value
  • Building an event system when you have two components that could just call each other
  • Creating abstract base classes with a single concrete implementation
  • Writing configuration files for values that never change
  • Adding database columns "we might need later"
  • Implementing caching before measuring whether there's a performance problem
  • Building a microservice when a function call would suffice

Examples

-- YAGNI violation: generic "processor" for one operation
class DataProcessor:
    def __init__(self, strategy, validator, transformer, output_format):
        self.strategy = strategy
        ...

-- Actually needed: one function
def process_csv_upload(file):
    rows = parse_csv(file)
    validate_rows(rows)
    save_to_db(rows)
-- YAGNI violation: premature abstraction
interface INotificationService
class EmailNotificationService implements INotificationService
class SMSNotificationService implements INotificationService  // "we might need this"
class PushNotificationService implements INotificationService  // "just in case"

-- Actually needed: you only send emails today
def send_welcome_email(user):
    mailer.send(to=user.email, template="welcome")

Boundaries

  • YAGNI does not mean ignore architecture. Good structure (separation of concerns, clear module boundaries) is not speculative — it makes future changes cheaper. YAGNI targets unused features, not good design.
  • YAGNI does not mean skip error handling. Handling known failure modes (network errors, invalid input, disk full) is not speculative — those things will happen in production.
  • YAGNI does not mean avoid extensibility at zero cost. If making code extensible costs nothing (e.g., using a map instead of a switch statement), do it. YAGNI targets costly abstractions.
  • Tension with DRY: Sometimes YAGNI wins — it's better to have two similar-but-not-identical functions than to prematurely unify them behind the wrong abstraction.

Code Review Checklist

  • Does this change introduce any code paths that aren't exercised by current requirements?
  • Are there parameters, configs, or options that only have one possible value today?
  • Could this abstraction be replaced by a direct implementation without loss of functionality?
  • Is this interface/trait/protocol justified by multiple concrete implementations?
  • Would a simpler approach work for the current scope?

Related Skills

  • kiss: When the issue is complexity rather than speculation
  • solid: When designing abstractions that are justified
  • dry: When deciding whether to extract a pattern (YAGNI says wait for 3 occurrences)

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.