greenfield-clean-breaks

star 4.6k

Greenfield clean-break review for refusing compatibility, finding inconsistent ownership, and deleting unearned branches, fallback states, duplicate paths, and premature abstractions. Use when the user explicitly releases compatibility pressure with phrases like greenfield, no users, clean break, refuse compatibility, remove slop, or asks whether a system should be redesigned from the ideal shape.

EpicenterHQ By EpicenterHQ schedule Updated 6/15/2026

name: greenfield-clean-breaks description: Greenfield clean-break review for refusing compatibility, finding inconsistent ownership, and deleting unearned branches, fallback states, duplicate paths, and premature abstractions. Use when the user says greenfield, no users, clean break, refuse compatibility, remove slop, simplify the design, or asks whether a system should be redesigned from the ideal shape.

Greenfield Clean Breaks

Use this skill when the user explicitly removes compatibility pressure or asks whether the current shape would survive if designed today.

References

Load on demand:

Examples:

Assume no users.
This is greenfield.
I want a clean break.
Do not preserve old behavior.
Refuse compatibility.
Delete the slop.
Would we add this if we started today?

This skill does not replace cohesive-clean-breaks or collapse-pass. It gives agents a sharper trigger for clean-break review when compatibility pressure has been released or was never earned.

cohesive-clean-breaks   broad redesign and asymmetric wins
collapse-pass           repeated deletion loop
greenfield-clean-breaks compatibility refusal and ideal-shape review

Compatibility is a product feature, not the baseline. Before preserving an old shape, name the contract that makes compatibility real.

published package API
deployed endpoint with users
durable storage format
sync wire format
documented config shape
migration reader for existing data
explicit product promise

If no contract exists, treat the old shape as removable. If a contract exists, decide explicitly: break, migrate, or preserve.

Core Rule

Write the ideal product sentence first.

<noun> owns <boundary>; <caller> enters through <single path>; <runtime> does <one job>.

Then judge the current code against that sentence.

If the sentence still works without a branch, option, helper, state field, or compatibility path, delete it.

Smell Catalog

In greenfield mode, look for:

two ways to do the same thing
two owners for the same value
fallbacks beside the canonical path
repair code in read paths
optional fields preserving old shapes
compatibility aliases
dual readers or dual writers
placeholder tables or services
default rows created for hypothetical future use
public types with no real consumer
helpers that only hide product decisions
test fixtures that preserve obsolete behavior
state copied across layers for convenience
branches that exist because an invariant is checked too late

These are not automatically wrong. They are suspicious. Keep one only when you can name the concrete product behavior it preserves.

Ownership Pass

Name one owner for every important value and invariant.

Use project vocabulary, not generic architecture words.

auth session       signed-in identity
route params       selected resource
database row       durable product fact
UI state           navigation choice
config file        project declaration
runtime actor      live coordination
sync engine        protocol bytes

If two layers can create, repair, reinterpret, or cache the same value, choose one owner and delete the other path.

Review Loop

Run this loop before editing:

1. Write the product sentence.
2. List current paths that create, read, update, delete, infer, cache, repair, or adapt the thing.
3. Name the owner of each value.
4. Mark each extra path as compatibility, fallback, convenience, repair, future option, or real product behavior.
5. Ask whether the product sentence survives if the path is refused.
6. If it survives, remove the path and record the refusal.
7. Re-run caller counts with rg.
8. Validate with targeted tests and typecheck.

Use this finding format before editing:

Product sentence:
  ...

Drift:
  ...

Value owners:
  ...

Code family created:
  ...

Greenfield clean break:
  ...

User loss:
  ...

Decision:
  refuse / keep / defer because ...

Go-to-Definition Awareness

In greenfield mode, any extra Go-to-Def hop has to earn its keep. A developer pressing Go-to-Def from a call site should land on the actual source of truth, not on an alias, a re-export, or a behavior-free wrapper. If nothing earns the hop, delete it.

Greenfield-specific Go-to-Def smells:

  • Re-export chains across packages where each hop adds nothing.
  • Adapter or proxy that wraps a real function with no behavior change.
  • Module-level object destructure-re-exported, so Go-to-Def lands on the destructuring line instead of the real export.
  • Type annotation form that obscures the value's identity (const fn: typeof Real = unreachable instead of const fn = unreachable satisfies typeof Real).
  • Public types hand-written over a factory's return shape, so Go-to-Def lands on the alias instead of the returned member.

See typescript and cohesive-clean-breaks for the per-change mechanics.

Earned Trigger Test

Do not add a table, public type, API field, route, service, config option, or lifecycle concept for a hypothetical future.

It is earned only when the product has a concrete operation that cannot live in the current owner.

Good earned triggers:

rename it
delete it
duplicate it
disable it
bill it
permission it separately
list it as a product object
audit it as an admin action
move it across an ownership boundary

Weak triggers:

maybe useful later
keeps options open
matches another product
makes tests easier
preserves an old mental model
supports old callers when the user said greenfield

Naming Bias

Prefer names that say what a path actually owns:

create*       construction
list*         read-only listing
resolve*      pure validation or route resolution
authorize*    permission checks
sync*         protocol movement
dispose*      teardown

Treat these names as review triggers:

ensure*
getOrCreate*
maybe*
legacy*
fallback*
compat*
default*
repair*

Those names can be valid, but they must prove their owner. For example, ensure* can be fine for migration or infrastructure setup where creation is the purpose. It is suspicious in a product read path.

Spec Updates

When a refusal lands, update the relevant spec.

Use this shape:

Candidate:
  ...

Refusal:
  ...

User loss:
  ...

Decision:
  ...

Trigger to revisit:
  ...

The trigger matters. Without it, "deferred" becomes a vague future bucket.

Stop And Ask

Pause before:

changing durable strings
deleting a published package API
changing auth or session schema
removing migration readers for existing on-disk user data
changing encryption or sync wire format
removing behavior the user has not actually released from compatibility pressure

A clean break can remove product compatibility. It does not silently break durable data formats or published contracts unless the user explicitly accepts that break.

Install via CLI
npx skills add https://github.com/EpicenterHQ/epicenter --skill greenfield-clean-breaks
Repository Details
star Stars 4,632
call_split Forks 351
navigation Branch main
article Path SKILL.md
More from Creator