How to Scope Non-Goals in Technical Specs

How to Scope Non-Goals in Technical Specs
Spec Coding Editorial Team · Spec-first engineering notes

The biggest predictor of whether a project ships on time isn't the goal list — it's the non-goal list. Teams that write explicit non-goals finish roughly on schedule. Teams that don't end up arguing, three weeks in, about whether something was always in scope. Every project I've watched ship late had a non-goal section that was either missing or one line long.

Published on 2026-03-01 · Updated 2026-05-06 · 7 min read · Author: Spec Coding Editorial Team · Review policy: Editorial Policy

Review Note

Reviewed May 6, 2026. This article is now part of the public topic path for the Spec-First Development Hub. It was rechecked for concrete examples, internal links, and indexable metadata before returning to the sitemap and feed.

What a non-goal actually is

A non-goal is a specific thing the current work will not do, even though a reasonable person might expect it to. The last clause is the important part. "We won't solve world peace" isn't a non-goal — nobody expected you to. "We won't handle partial refunds, even though the full refund flow looks similar" is a non-goal, because someone will try to sneak it into scope two weeks from now.

Good non-goals read like commitments, not aspirations. "In this release" or "in this milestone" should be implicit. The test is: if someone asks during implementation "hey, should we also do X?" — is the answer already in the document?

Where non-goals come from

Most non-goals aren't invented. They're extracted from conversations that already happened. Sources I mine for them:

The practice is: every time you notice yourself saying "oh but not that," write it down. That's your non-goal list.

The three shapes I use

Not every non-goal reads the same. I pattern them into three shapes depending on why they're not in scope.

Deferred

The thing is real, we'll probably do it, but not now.

Non-goal: Partial refunds
Reason: Out of scope for v1. Planned for v2 (tracked in JIRA-1234).
The full refund flow will be implemented in a way that allows later
extension without restructuring the refund table.

Deferred non-goals need a forward pointer. Without one, they come back in a scope-creep argument.

Rejected

We considered it and decided no.

Non-goal: SMS-based password reset
Reason: SMS delivery has a 3% failure rate in our current provider's
geography, incompatible with the 99% delivery expectation for password
reset. Decision is final unless we change provider.

Rejected non-goals prevent re-litigation. Include the reason or someone will revisit it during implementation.

Out of domain

The thing belongs to a different system or team.

Non-goal: Auth token refresh logic
Reason: Owned by the identity team. This feature consumes the
existing refresh behavior unchanged. Any refresh bugs go to them.

Out-of-domain non-goals prevent accidental cross-team work. Name the owning team so escalation is clear.

How many non-goals is enough

I aim for 3-6 non-goals per mid-sized feature. Below three, you probably haven't thought about adjacent scope. Above six, you're either listing things no one would have asked for, or the feature is too ambitious.

Quick sanity check: read your non-goals back and ask "would anyone actually have wanted this?" If the answer is no, delete it — it's noise. If the answer is "yes, and they're going to ask during implementation," keep it.

Non-goals and acceptance criteria interact

A subtle point: if a non-goal is "we don't support X," your acceptance criteria need to cover what happens when someone tries X anyway. It's not enough to say "we won't build partial refunds." The spec also needs: "When a user attempts a partial refund via the API, the endpoint returns 400 with error code 'unsupported_refund_type' and a link to the docs."

Non-goal without a handling AC = user gets a 500 and a support ticket. Non-goal with a handling AC = user gets a clear rejection and bounces off cleanly.

When non-goals need to move

Sometimes a non-goal becomes a goal mid-project. That's allowed, but the process matters. The rule I use:

Language patterns that work

Phrasings I've found keep non-goals from being ignored:

Phrasings that get ignored:

The meta-non-goal

One I always include near the top of a spec:

Meta non-goal: This spec does not describe implementation.
Architectural choices and data structures are engineering decisions,
not product decisions. Changes to the architecture do not require spec
changes unless they alter observable behavior.

This prevents the spec from becoming a design doc, which is how specs balloon to 30 pages and stop being useful as review artifacts.

The bottom line

Non-goals are a cheap way to buy scope discipline. They cost five minutes to write and save the team an argument every week of implementation. If your spec has a goal list but no non-goals, it's only half done. Every time I've skipped this step, I've regretted it in the second week.

Review drill

Use the non-goals section to end scope arguments early. A good non-goal is not a polite "later"; it names the work that is excluded, why it is excluded, and what would reopen the decision.

After review, copy the strongest non-goals into the ticket or release plan so implementation does not quietly absorb them.

Example: "multi-currency settlement is out of scope" is useful only if the spec also says single-currency assumptions remain, invoices store currency explicitly, and FX handling needs a separate migration plan.

Worked Review Example

For a reporting dashboard, "custom report builder is out of scope" is still too loose. Say the release includes fixed filters only, saved views are not supported, CSV columns follow the current export contract, and ad hoc SQL-style grouping needs a separate data-model review. That lets design, backend, and QA reject scope creep with the same sentence.

Release Note Example

In the release checklist, restate the highest-risk non-goal in operational language. For example: "This release does not migrate historical exports. Existing CSV files keep their current column order, the new report_version field applies only to exports created after deployment, and support should route historical-export requests to the existing manual process." That prevents a non-goal from being lost between the spec, QA plan, and support handoff.

API Boundary Example

For an API change, write non-goals with the same precision you use for the contract. "No webhook changes" should become: "This release does not add a new webhook event, does not change the invoice.updated payload, and does not require consumers to store tax_region. Partner notification, schema versioning, and replay behavior are tracked in API-217." That wording gives backend, QA, support, and partner teams the same boundary.

During review, check that the non-goal matches the test plan: no new schema migration, no new response field, no new retry policy, no new dashboard metric, and no hidden feature flag that changes public behavior.

Keywords: non-goals · scope definition · technical spec · spec writing · scope creep

Topic Path

Read the hub first, then use these adjacent examples and templates to place this article inside the full workflow.

Editorial Note