← Software design practices guides

How to use non-goals to prevent the wrong work

How-To Software design practices Beginner 1101012HOWTO-1101012

HOWTO-1101012Software design practicesBeginner

This guide shows you how to use non-goals to prevent the wrong work with SpecDD in a spec-driven development workflow.

Non-goals are one of SpecDD’s most practical design tools. A good non-goal blocks a mistake that a reasonable human or agent might make while implementing the spec. It keeps work from spreading into adjacent behavior, dependencies, layers, or product decisions.

In SpecDD, most non-goals belong in Must not. Use them to say what the subject must not do, even if that work looks nearby or tempting.

Short answer

Write non-goals as specific Must not rules for plausible local mistakes. Use Forbids instead when the boundary is a blocked dependency, path, tool, library, module, or access pattern. Keep non-goals short and meaningful. Do not list every unrelated thing the subject does not do.

When to use this guide

Use this guide when:

The design idea

Required behavior says what the unit should do. Non-goals say where it should stop. Both are design information.

Without non-goals, an implementation can satisfy every Must rule and still do the wrong work. For example, a UI component can show validation feedback while also duplicating validation rules. A storage adapter can save trips while also deciding which itinerary items are visible. A feature can add itinerary behavior while also changing booking flow.

Non-goals prevent those nearby mistakes.

Steps

1. Identify plausible wrong work

Ask:

Only write non-goals for mistakes that are plausible in this local context.

2. Write focused Must not rules

Good:

Must not:
  Change destination search ranking.
  Persist itinerary items directly from UI components.
  Purchase bookings or tickets.

Weak:

Must not:
  Break anything.
  Do unrelated work.
  Make bad architecture choices.

The good rules are reviewable. The weak rules are just anxiety in spec form.

3. Separate behavior from dependency bans

Use Must not for behavior:

Must not:
  Decide whether itinerary input is valid.

Use Forbids for blocked access or dependencies:

Forbids:
  ../adapters/*
  direct browser storage access

This distinction helps reviewers understand whether the rule blocks a behavior or an implementation path.

4. Avoid unrelated negative lists

Bad:

Must not:
  Send email.
  Process payments.
  Render charts.
  Manage authentication.
  Start background jobs.

If none of those mistakes are plausible for the local subject, the list adds noise. A noisy spec becomes harder to maintain and easier to ignore.

5. Use non-goals to preserve ownership

For a storage adapter:

Must not:
  Change place names.
  Move itinerary items between days.
  Decide which itinerary items are visible.

These non-goals keep storage focused on persistence.

For a component:

Must not:
  Decide itinerary validation rules.
  Persist itinerary items directly.

These non-goals keep UI focused on presentation and interaction.

6. Review non-goals before implementation

Before code changes, ask:

Good non-goals protect the work. Bad non-goals make the spec noisy.

7. Update non-goals when boundaries change

Removing or weakening a non-goal changes future implementation authority. Treat it as a design change. If a component is now allowed to own a decision it previously did not own, reviewers should understand why the boundary moved.

Example

Spec: Itinerary Form

Purpose:
  Capture itinerary item input and show validation feedback.

Owns:
  ./itinerary-form.jsx
  ./itinerary-form.test.jsx

Must:
  Submit place name and trip day to itinerary behavior.
  Show validation feedback returned by itinerary behavior.

Must not:
  Decide whether an itinerary item is valid.
  Persist itinerary items directly.
  Fetch destination search results directly.

Forbids:
  ../adapters/*
  direct browser storage access

Done when:
  The component shows validation feedback.
  The component does not import storage adapters.

This spec gives the component enough authority to implement UI behavior and enough limits to prevent wrong work.

Common mistakes

How to verify the result

The non-goals are useful when:

← Software design practices guides