Documentation

Development driven by specifications

Find out how specifications turn product intent into clear scope, acceptance criteria, executable plans, tested changes and reviewable pull requests.

Coroid uses specification-driven development: the specification remains attached to a piece of work from planning through testing and review, ensuring every stage operates from the same definition of success.

Rather than starting with a single sentence and figuring out the details while writing code, Coroid converts the request into explicit scope, exclusions and acceptance criteria. That document then serves as the source of truth for the plan, implementation, tests and final review.

What is specification-driven development?

Specification-driven development is a method of building software based on an agreed, testable description of the desired outcome. The specification outlines what will change, what will remain unchanged, which constraints apply and how a reviewer can confirm the work was successful.

It separates two decisions that are easily confused:

  • The specification defines what success looks like.
  • The implementation plan defines how to achieve it.

This separation allows you to adjust the scope before any code is written, without prescribing the implementation too early. In Coroid, you can also enable the optional SDLC workflow when you want to approve the intent and specification prior to starting planning. SDLC workflow if you wish to approve the intent and specification before planning begins.

How the workflow functions in Coroid

  1. Describe the desired outcome. Provide Coroid with the result you need, the relevant context and any constraints or non-goals.
  2. Review the specification. Check the scope, exclusions and acceptance criteria on the task's Specification tab. Specification tab.
  3. Approve the plan. The architect converts the agreed outcome into ordered implementation steps.
  4. Build and verify. Developer and QA agents use the same criteria to implement the change and prove each promised behaviour.
  5. Review the pull request. The delivered change includes the plan, test results, findings and evidence that correspond to the original specification.

The result is full traceability from product intent to the code and the evidence seen by a human reviewer. See How a task becomes a COROID_TERM_0 for the complete execution path. How a task becomes a pull request for the full execution path.

Why include this extra step?

An instruction such as "add caching to the user lookup" can be implemented in at least four different ways, with no clear definition of what counts as complete. An agent will pick one of these options—whether it matches your preference is pure luck.

The specification makes that choice explicit before implementation starts, at the point when it’s cheapest to change your mind.

It also provides a benchmark for verification. Without acceptance criteria, the question "did this work?" reduces to "do the tests still pass?", which is a far less meaningful measure.

What a specification contains

PartWhat it answers
ScopeWhat will change
Out of scopeWhat is deliberately excluded, to prevent the change from expanding unnecessarily
Acceptance criteriaHow anyone can confirm the work was successful
ContextConstraints, conventions and prior decisions that apply

You can read and edit it on the task's Specification tab before execution starts. For the work description and supporting context that feed this process, see Describing what you need. Specification tab before execution starts. For the work description and supporting context that feed this process, see Describing what you need. Describing what you need.

Worked example: from brief to testable specification

Suppose the original brief is:

Add caching to the user lookup so repeated requests are faster.

That outlines the desired outcome but leaves key decisions unresolved. A useful specification converts those choices into clear boundaries and checks:

Scope
- Cache successful user lookups by user id for 60 seconds.
- Invalidate the cached entry when the user record is updated.

Out of scope
- Do not cache failed lookups.
- Do not change the public signature of getUser.

Acceptance criteria
- Two lookups for the same user id within 60 seconds call the data source once.
- Updating that user invalidates the existing cache entry.
- A cache miss preserves the current result and error behavior.

The plan can now select an appropriate implementation, QA can turn the criteria into tests, and the reviewer can compare the pull request with the promised behaviour.

What makes acceptance criteria effective?

They must be checkable by someone who wasn’t involved in the initial discussion.

Weak:

Caching works correctly and performance is improved.

Strong:

- Repeated lookups for the same user id within 60s hit the cache, verified
  by a test asserting the data source is called once across two lookups.
- Cache entries are invalidated when the user record is updated.
- A cache miss behaves identically to today, including error handling.
- No change to the public signature of `getUser`.

The second version tells the developer agent what to build, tells the QA agent what to test, and tells you what to check on the pull request. The first version leaves each of those decisions open.

Scope lines are just as important as criteria

The most common reason for an oversized pull request is not an agent exceeding its brief — it is a specification that never states where the brief ends.

If you do not want the surrounding module refactored while the change is in progress, specify this explicitly. “Do not alter the call sites” is a valid and useful instruction.

Common specification mistakes

MistakeBetter approach
Describing the implementation rather than the desired outcomeState the required behaviour and constraints, then let the plan determine the implementation.
Using terms like “fast”, “secure” or “works correctly”Replace these with an observable threshold, behaviour or test.
Omitting non-goalsName any adjacent code, interfaces or behaviours that must stay unchanged.
Combining unrelated outcomesSplit the work so that one Task results in one reviewable pull request.
Copying a ticket without verifying underlying assumptionsInclude the context and decisions that the repository cannot capture.

When you disagree with the specification

Edit it. The specification is a living document until execution begins; correcting it is far cheaper than fixing the resulting code.

If the specification shows the work actually comprises two separate tasks, divide it into two Tasks. Each Task should produce one pull request that a single person can review quickly.

What happens next

For any change beyond a minor tweak, the specification forms the basis of the plan. See Tasks, plans, sprints and lanes, which explains how the work is divided and approved prior to writing code.

Frequently asked questions

Is a specification the same as a technical design?

No. A specification defines the required outcome and its boundaries. A technical design or implementation plan outlines the architecture and steps needed to achieve that outcome.

Does every change require a lengthy specification?

No. A small, unambiguous change may need just a few lines describing the scope and acceptance criteria. The specification should eliminate meaningful uncertainty, not add unnecessary formality.

Who should approve the specification?

The person responsible for the outcome should verify that the scope and criteria align with the team’s needs. Technical, security or compliance reviewers can contribute when their requirements affect success.

Can a specification be changed after work begins?

Yes, but any change must create a new version and prompt a review of the related plan and ongoing work. Unnoticed scope changes disrupt the link between the original request and the delivered pull request.