How Do You Write Good Requirements for a System You’ve Never Built Before?
The question contains a hidden assumption worth surfacing: that good requirements are requirements you get right the first time. They aren’t. Good requirements are requirements that are honest about current knowledge, traceable to their source, and structured so they can be refined without cascading chaos. That is true for mature programs with decades of heritage data. It is doubly true for novel systems where the design space is still open.
Here is a practical framework for generating, structuring, and iterating requirements when you are starting from first principles.
The Most Important Distinction: What vs. How
Before you write a single requirement, commit this rule to memory: a requirement states what a system must do or be, not how it accomplishes that. Violating this rule is the single most common mistake on novel system programs, and it is particularly dangerous early in development when the design space should remain open.
A what requirement:
The vehicle shall maintain cabin temperature within ±2°C of the set-point under all specified operating conditions.
A how requirement disguised as a what:
The vehicle shall use a variable-speed compressor to maintain cabin temperature within ±2°C of the set-point.
The second statement has embedded a design decision—variable-speed compressor—into the requirement layer. If the thermal team later discovers that a heat-pump configuration is more efficient for your power architecture, they cannot make that choice without a formal requirement change. You have artificially constrained the design without meaning to.
The practical test: ask “does this statement allow more than one design solution?” If yes, it is likely a requirement. If it describes a specific implementation, it belongs in a design document, an interface control document, or a trade study—not in the requirement baseline.
This becomes more challenging with software-intensive systems, where the boundary between behavior and implementation can blur. The discipline still holds: require observable, verifiable behaviors at the system boundary. Let the architecture emerge from the design process.
When There Is No Heritage: ConOps and Use Cases as Requirements Sources
Novel systems have no previous program to reference. You cannot pull up a requirements database from the last generation and mark up the delta. You have to generate requirements from scratch, and two tools are purpose-built for this situation: the Concept of Operations (ConOps) and use cases.
The Concept of Operations
A ConOps is not a marketing document. It is a structured narrative of how the system will be operated, by whom, under what conditions, and for what purpose. Written before the design begins, it forces a conversation about operational reality that engineers often skip in their rush to start designing.
A useful ConOps covers:
- Operational scenarios: the nominal mission, expected off-nominal conditions, and failure modes the operator must manage
- Stakeholders and users: who interacts with the system and what their needs and constraints are
- Operating environment: thermal, vibration, EMI, altitude, duty cycle—the physical context in which the system lives
- System boundaries: what the system interfaces with, what it depends on, what depends on it
Each sentence in a well-written ConOps is a potential requirement source. When you write “the operator shall be able to reconfigure the system without tools during a 15-minute maintenance window,” you have implicitly generated multiple requirements: a time constraint, a human factors constraint, and an accessibility requirement. Extracting these systematically is how you convert operational knowledge into requirement statements.
Use Cases
Use cases work at a finer grain than ConOps. A use case describes a specific interaction between a user (or external system) and the system under development, with a defined trigger, a sequence of steps, and a defined outcome.
For requirements generation, the most useful parts of a use case are the preconditions (what must be true before the interaction begins), the postconditions (what must be true after it completes), and the failure paths (what happens when things go wrong). Each of these generates requirements.
A use case for “operator initiates emergency shutdown” might generate:
- A response time requirement (the system shall reach a safe state within N seconds of shutdown command)
- A state requirement (all actuators shall be de-energized before the shutdown sequence completes)
- An indication requirement (the system shall provide unambiguous confirmation of shutdown state to the operator)
- An audit requirement (all shutdown events shall be logged with timestamp and initiating condition)
Use cases are particularly powerful for identifying requirements you would not have thought to write from a pure functional decomposition. The failure paths in particular surface safety, fault detection, and recovery requirements that are invisible until you walk through the scenario step by step.
Derived Requirements: Design Knowledge in Requirement Form
Early in a program, your requirements describe system-level behavior. As design work proceeds and the architecture takes shape, a second category of requirements emerges: derived requirements.
A derived requirement is one that is not traceable directly to a stakeholder need but is instead generated by design decisions. It flows downward from system to subsystem, or from architecture to component.
Example: a system-level requirement states that the vehicle shall operate continuously for 72 hours without maintenance. The power systems team determines that this implies the battery pack must deliver at least 4.2 kWh under worst-case load. That energy capacity figure is a derived requirement—it was not in the stakeholder statement, but it is a necessary implication of the design architecture and the original requirement.
Derived requirements are not a sign that the original requirements were wrong. They are evidence that design work is happening. The obligation is to keep the parent-child relationship explicit: every derived requirement should trace to the design decision that generated it, and that design decision should trace to the parent requirement it serves. Without this traceability, derived requirements become orphaned constraints that nobody can justify, challenge, or remove when the design changes.
Managing this traceability manually—in spreadsheets, in DOORS databases with hand-maintained links—is where programs typically lose coherence. The requirement exists, but the rationale for it disappears, and two years later nobody can explain why the subsystem carries a constraint that no longer makes engineering sense.
Parametric vs. Qualitative Requirements: Knowing When to Use Each
There is pressure, particularly from reviewers and program managers, to quantify everything. Numbers feel rigorous. They feel like engineering. But premature quantification is its own form of requirements failure.
Use parametric requirements when:
- The physics of the problem constrain you to a number (mass, power, frequency, response time)
- You have data—from test, from analysis, from heritage—sufficient to set the number with engineering confidence
- The number is verifiable by a defined test or analysis method
Use qualitative requirements when:
- You don’t yet have the analysis to set a defensible number
- The requirement describes a capability or property that is better verified by demonstration or inspection than by measurement
- You are writing interface requirements where the specific values will be resolved through agreement between interfacing organizations
The honest approach on novel programs is to write qualitative requirements as placeholders where the data does not yet exist, and to explicitly flag them for later refinement with a TBD or TBR (To Be Resolved) designation. A requirement that reads “the system shall provide adequate thermal margin” is not a good permanent requirement—but it is better than a number invented to satisfy a review board that will become an unachievable constraint on the design team.
TBD values are not failures. They are explicit admissions of current knowledge boundaries. What they require is active management: each TBD should have an owner, a resolution method (analysis, test, trade study), and a scheduled closure date.
On the Fear of Writing Wrong Requirements
Most engineers who are new to requirements work share a common anxiety: what if I write the wrong requirement? What if I miss something? What if the system changes and my requirement baseline is out of date?
This fear produces two failure modes. The first is paralysis—requirements don’t get written because they might be wrong. The second is over-specification—requirements are written at such fine granularity that every design decision gets locked into the requirement layer, producing a document that is both unmaintainable and already obsolete by the time it is baselined.
The reframe that makes both failure modes easier to avoid: requirements are not a contract you write once and then defend forever. They are a structured, version-controlled record of current understanding, with explicit traceability to the reasoning behind each statement. The goal is not perfection. The goal is intellectual honesty and traceability.
In practice, this means:
- Write requirements at the right level of detail for the current stage of program maturity. System requirements before design reviews should describe system behavior, not subsystem architecture.
- Document your rationale. Every significant requirement should have an attached rationale explaining why it exists and what it derives from. When the requirement changes, the rationale is what allows reviewers to evaluate whether the change is justified.
- Treat change as expected, not exceptional. Requirements change because understanding improves. The process for handling that change—change control, impact assessment, re-verification—is a feature of a healthy program, not a symptom of poor requirements work.
How Iterative Refinement Works in Practice
Iteration in requirements is not the same as instability. A requirements baseline that changes thoughtfully—with each change traced, justified, and assessed for downstream impact—is a sign that the program is learning. A requirements baseline that never changes is either on a very mature program or on one where problems are accumulating undetected.
A practical rhythm for novel system programs:
- Generate from ConOps and use cases at program start. Write at the system level. Flag TBDs explicitly.
- Review against stakeholder needs before the first design review. Are the requirements traceable to actual needs? Have you imposed solutions?
- Generate derived requirements as architecture decisions are made. Maintain parent-child traceability explicitly.
- Resolve TBDs as analysis and test data becomes available. Track closure.
- Conduct regular requirements audits at major program milestones. Identify requirements that are no longer consistent with current design knowledge. Change them formally.
The challenge in this process is maintaining traceability as the requirement set evolves. When a parent requirement changes, what downstream requirements does it affect? When a design decision is revised, which derived requirements need to be revisited? In a growing, novel system program, these questions become genuinely difficult to answer with manual tooling.
This is the problem that tools like Flow Engineering are built for. Flow Engineering is designed around the reality that requirements evolve—it maintains a live graph of relationships between requirements, design artifacts, and verification methods, so that when a requirement changes, the impact propagates visibly rather than getting lost in spreadsheet columns. For teams working on novel systems where derived requirements are accumulating rapidly and ConOps-level understanding is still sharpening, the ability to update a requirement and immediately see what else is affected is not a convenience—it is what keeps the traceability from collapsing under the weight of iteration.
Flow Engineering also surfaces the rationale and parent links that make TBD resolution trackable, so that “we need to close this requirement by CDR” is an action with a visible owner rather than a note in meeting minutes nobody can find.
Practical Starting Points
If you are beginning requirements work on a novel system today:
-
Write the ConOps first. Before requirements, before architecture. Three to five pages that describe what the system does, who uses it, and in what environment. Every operational scenario is a requirements source.
-
Draft five to ten use cases for the most operationally critical functions. Walk through the failure paths explicitly. Extract requirements from preconditions, postconditions, and failures.
-
Separate what from how in every requirement you write. If you find yourself describing an implementation, move it to a design document and write the performance or behavioral requirement it must satisfy.
-
Mark TBDs explicitly with owners and closure plans. Do not invent numbers to fill gaps.
-
Establish traceability from the start. Connecting requirements to stakeholder needs and to verification methods from day one is far easier than retrofitting traceability to a mature requirement set.
-
Expect to iterate. Novel systems require it. The discipline is in managing the iteration with visibility—not in getting it right before the work begins.
The engineering teams that produce the best requirements for novel systems are not the ones with the most experience in their specific domain. They are the ones who treat requirements as a living knowledge artifact, who are honest about what they don’t know, and who build the traceability infrastructure to manage change without losing the thread of why each requirement exists.