A system that operates without a software safety case is operating on trust — trust that the hazard analysis was complete, that the design controls are correct, and that the verification evidence is sufficient. For a commercial product, that trust is defensible. For a military system whose failure modes include energetic releases, platform loss, or fratricide, it is not. MIL-STD-882E, the Department of Defense standard for System Safety, provides the structured process by which that trust is replaced with documented, reviewed, and accepted evidence. The software safety case is the artifact that captures that evidence and makes the argument that residual risk is acceptable.
This article is a practitioner's guide to building a software safety case under MIL-STD-882E. It covers the standard's task structure and its software-specific provisions, the hazard analysis chain from preliminary identification through software hazard analysis (SwHA), the derivation of Software Safety Requirements (SSRs) from hazard causes, the design controls that implement those requirements, the verification evidence that demonstrates their correct implementation, and the risk acceptance process that closes the case. Engineers new to defense safety programs will find it a map of the terrain; experienced practitioners will find it a reference for the specific outputs and traceability expected by government reviewers.
MIL-STD-882E overview: system safety from concept to disposal
MIL-STD-882E defines system safety as a planned, disciplined approach to identifying and managing hazards throughout a system's lifecycle — from concept exploration through disposal. The standard organizes its requirements into tasks grouped into five categories: Program Management and Control, Design Requirements, Supportability, Training, and Assessments. The contracting activity selects tasks appropriate to the program's risk profile and specifies them in the Statement of Work. The contractor performs those tasks and delivers the results as Contract Data Requirements List items.
For software-intensive military systems, five tasks dominate the engineering effort:
- Task 205 — Software Safety Requirements Analysis: identification of all safety-critical software functions and derivation of Software Safety Requirements to control identified hazard causes.
- Task 206 — Software Safety Design Analysis: analysis of the software design to verify that safety requirements are correctly allocated and that no new hazard causes are introduced by design decisions.
- Task 301 — Safety Assessment: a milestone-driven assessment of whether residual risk is acceptable, documented in a Safety Assessment Report (SAR).
- Task 302 — Test and Evaluation Safety: ensuring that safety controls are in place before any test activity involving hazardous energy or operational modes.
- Task 303 — System Safety Program Reviews: formal reviews at which the System Safety Working Group (SSWG) presents hazard status, open risk items, and evidence of control effectiveness to the program office.
The risk matrix at the center of MIL-STD-882E plots Severity against Probability. Severity runs from Catastrophic (Category I: death, system loss, severe environmental damage) through Critical (Category II: severe injury, major system damage) and Marginal (Category III: minor injury, minor system damage) to Negligible (Category IV: less than minor injury or damage). Probability runs from Frequent (likely to occur often over the system's life) through Probable, Occasional, Remote, and Improbable. Each cell in the resulting 4×5 matrix carries a Hazard Risk Index (HRI) that determines who must accept the residual risk after controls are applied.
The HRI is not a mathematical product — it is an ordinal ranking defined by the program's risk matrix, which the SSPP establishes. A Catastrophic/Frequent hazard (HRI 1) requires acceptance by the Milestone Decision Authority; a Negligible/Improbable hazard (HRI 20) is acceptable at working-group level. The practical implication for software engineers is that the analysis products they produce — hazard worksheets, SwHA rows, SSRs, verification records — feed directly into a risk management process with defined authority levels. Gaps in the analysis leave risk at an indeterminate level that no authority can accept.
Preliminary hazard analysis: finding safety-critical software functions
The Preliminary Hazard Analysis (PHA) is performed early in system development, typically before detailed requirements are finalized, using functional decomposition of the system and operational concept documentation. Its purpose is to identify hazards at the system level, assign initial severity and probability ratings, and identify which system functions — hardware, software, human, or procedural — contribute to each hazard. The PHA does not require detailed design knowledge; it works at the level of "what can this system do that could harm people, equipment, or the environment?"
PHA inputs typically include:
- System concept of operations (CONOPS) and operational scenarios
- System functional requirements and top-level architecture
- Energy sources and hazardous materials inventory
- Interface definitions (to adjacent systems, to operators, to the environment)
- Historical hazard data from similar systems
PHA outputs include a populated Hazard Log with unique hazard identifiers, natural-language hazard descriptions, initial HRI ratings, and a list of contributing functions. For a fire control system, the PHA might identify "Unintended weapons release" as a Catastrophic hazard (Category I) and list as contributing functions: the engagement authorization software, the weapons release command channel, the arming interlock logic, and the operator interface. That list of contributing functions is the entry point for all subsequent software safety analysis.
The distinction between a hazard and a failure mode matters here. A hazard is a condition with potential for harm — "unintended weapons release" is a hazard. A failure mode is a mechanism by which a component can malfunction — "spurious assertion of FIRE_COMMAND output" is a failure mode. The PHA identifies hazards; subsequent analyses identify the failure modes that contribute to them. Conflating the two in the hazard log is the most common structural error in early-program safety analysis, and it propagates forward into SwHA tables that are difficult to trace.
Software's contribution to system hazards is qualitatively different from hardware's. A hardware component has a physical failure rate that can be estimated from field data or accelerated testing. Software defects are deterministic: given specific inputs, a defective function always produces the wrong output. Software does not wear out, and it does not have a meaningful mean time between failures in the same sense as a relay or a valve. The probability assigned to a software contribution to a hazard is therefore a judgment about the likelihood that the software contains a defect relevant to that hazard, weighted by the likelihood that the specific input conditions that would trigger it occur in operation. This judgment is informed by software complexity, the rigor of the development process, and the depth of testing — not by empirical failure data.
Software hazard analysis: mapping software to hazards
Software Hazard Analysis (SwHA) is the task that connects the system-level hazard log to specific software behaviors. For every hazard in the PHA that lists a software function as a contributor, the SwHA asks: what must the software do incorrectly (or fail to do) in order for this hazard to occur? The answer enumerates software failure modes, which become the causal chains that SSRs must address.
Software failure modes fall into five canonical categories:
- Incorrect output: the function executes and produces an output, but the output value is wrong — a command outside the valid range, a state flag set when it should be clear, or a calculation result with an arithmetic error.
- No output (omission): the function fails to produce an output that the system depends on — a watchdog that stops resetting, a health monitor that fails to report a fault, a safety interlock that does not assert the inhibit signal.
- Late output: the function produces the correct output, but not within the required time window — a real-time constraint violation that causes the system to proceed with a stale or absent input.
- Spurious output: the function produces an output that was not requested or that occurs at a time when it is not valid — an unsolicited command that triggers an actuator during a mode where that command is hazardous.
- Output to wrong destination: the function routes a valid output to an incorrect interface — a command intended for one subsystem is delivered to another due to a routing or addressing error.
The SwHA worksheet structure follows a standard pattern. Each row corresponds to one (hazard, software function, failure mode) triple. The columns record the hazard identifier, the hazard description, the software function name, the failure mode category, the effect of the failure mode on the system hazard, the severity of the resulting harm, the probability (as a qualitative assessment), the HRI, and the derived SSR identifier that addresses this row. A SwHA table for a flight control system might have several hundred rows; for a simpler command and control terminal, perhaps thirty to sixty.
Traceability is the operational metric of SwHA quality. Every PHA hazard with a software contribution must appear in the SwHA. Every software function listed in the PHA must have at least one SwHA row. Every SwHA row must link to at least one SSR. And every SSR must trace back to at least one SwHA row. Traceability gaps discovered during government safety reviews are the most common cause of SwHA rework in the review cycle.
The SwHA also identifies software requirements that serve safety functions not because they prevent a hazard directly, but because they enable a safety monitor to detect a hazard precursor. These monitoring requirements are as important as direct control requirements — a monitor that fails silently removes the system's ability to transition to safe state before a hazard occurs. They require the same SSR formulation and verification rigor as direct inhibit requirements. See also: formal verification for defense software for techniques that can mathematically demonstrate the absence of specific failure modes in safety-critical modules.
Safety-critical function identification and Software Safety Requirements
A safety-critical software function is any function whose failure mode appears in the SwHA as a contributor to a Catastrophic or Critical hazard. The identification of safety-critical functions is the precondition for the allocation of additional design rigor: higher code coverage targets, mandatory peer review, independent verification, and formal analysis.
The Software Criticality Index (SCI) formalizes this. Each safety-critical function is assigned a criticality category based on the worst-case consequence of its failure: Category I (Catastrophic), Category II (Critical), Category III (Marginal), Category IV (Negligible). The SCI drives the selection of software safety requirements and the depth of verification applied to each function. A Category I function — say, the final authorization check before a weapons release command — warrants the most rigorous treatment the program can apply. A Category IV function — a diagnostic log writer — warrants none of the additional rigor.
Software Safety Requirements (SSRs) are derived directly from SwHA rows. For each identified failure mode, the SSR specifies the software behavior that prevents, detects, or mitigates that failure mode. The canonical SSR forms are:
- Positive constraint: "The software shall assert SAFE_STATE output within 50 ms of detecting loss of valid heartbeat from the primary sensor." (Addresses: late/no output failure mode in the sensor monitoring function.)
- Negative constraint: "The software shall not assert WEAPONS_RELEASE_COMMAND unless ARM_CONFIRMED, TARGET_VALIDATED, and OPERATOR_AUTHORIZED have all been continuously asserted for at least 500 ms." (Addresses: spurious output failure mode in the release authorization function.)
- Range constraint: "The commanded azimuth output shall be within ±180 degrees. Any computed value outside this range shall cause the software to enter FAULT_HOLD state without outputting the command." (Addresses: incorrect output failure mode in the fire control computation function.)
- Monitoring requirement: "The software shall compare commanded thrust with measured thrust on each 10 ms cycle and set THRUST_FAULT_FLAG if the difference exceeds 15% for three consecutive cycles." (Enables hazard precursor detection.)
Each SSR is tagged with a unique identifier (e.g., SSR-FC-007), allocated to a specific software component in the architecture, and entered into the traceability matrix linking it to its parent SwHA rows. During detailed design, each SSR must be further allocated to a specific requirement in the Software Requirements Specification (SRS) or Software Design Document (SDD). The SRS/SDD requirement inherits the SSR tag, enabling automated traceability tools to propagate the safety designation through the requirements hierarchy and into test case selection.
SSRs that cannot be verified by test or analysis are indicators of an architectural problem. If the safety behavior cannot be independently confirmed, either the software architecture does not expose the relevant state for observation, or the SSR is formulated in terms that are not measurable. Both problems require resolution before design progresses to implementation. An SSR without a feasible verification method is not a safety control — it is a statement of intent.
Software design controls for safety
Design controls are the architectural and implementation patterns that make the software behaviors required by SSRs reliable in the presence of faults. Each design control is selected based on the failure mode it addresses and the consequence severity of that failure mode. There is no universal pattern — the appropriate control depends on the system architecture and the specific hazard cause being mitigated.
The most broadly applicable patterns in military software are:
Watchdog supervision. A hardware or independent software watchdog requires the safety-critical application to actively assert a reset signal on each processing cycle. Failure to assert the reset — whether because the application crashed, entered an infinite loop, or became otherwise non-responsive — causes the watchdog to time out and force a transition to safe state. The safe state is defined by hardware: de-energize outputs, set inhibits, close valves. The watchdog does not need to understand why the application failed; it only needs to know that normal operation has ceased.
Positive arming sequences. Hazardous commands require multiple independent enable conditions to be simultaneously satisfied before the command can be issued. No single software fault, single sensor failure, or single operator error can satisfy all conditions simultaneously. The classic example is a weapons arming and release sequence: arming requires a separate hardware arming circuit, a software authorization state, a proximity or targeting condition, and an operator confirmation, all within a time window. Removing any one of these removes the ability to fire.
Fail-safe state machines. Safety-critical control logic is implemented as an explicit finite state machine with a defined safe default state. Every input that would cause an invalid state transition is mapped to the safe state rather than an undefined behavior. The state machine is designed so that loss of power, loss of communications, or loss of sensor validity all converge on the safe state — there is no path from a fault condition to a hazardous command. Consider a simplified example for an interlock controller:
STATE_INIT,
STATE_STANDBY,
STATE_ARMED,
STATE_ENGAGE,
STATE_SAFE /* default/fault state */
} InterlockState;
/* Any unrecognized input or invalid transition maps to STATE_SAFE */
InterlockState transition(InterlockState current, Event ev) {
switch (current) {
case STATE_STANDBY:
if (ev == EVT_ARM_CONFIRMED) return STATE_ARMED;
break;
case STATE_ARMED:
if (ev == EVT_ENGAGE_AUTHORIZED) return STATE_ENGAGE;
if (ev == EVT_DISARM) return STATE_STANDBY;
break;
/* All other cases fall through to safe state */
default: break;
}
return STATE_SAFE;
}
Plausibility monitoring. An independent monitoring process compares output commands against physical constraints. A commanded acceleration that exceeds the vehicle's documented maximum capability is implausible and may indicate a computation error or corrupted input. The monitor intercepts and blocks the implausible command, logs the event, and alerts the health management system. The monitoring logic must be independent of the computation logic — if both use the same algorithm, a systematic defect affects both identically and the monitor provides no protection.
Defensive input validation. Every safety-critical function validates its inputs against defined valid ranges before processing them. Inputs outside the valid range do not cause computation on invalid data — they cause the function to assert a fault condition and enter a defined error-handling path. The validation logic must cover not just range checks but also temporal validity (is this the most recently sampled value or an aged reading?), source validity (did this value come from the expected sender?), and consistency (does this value agree with corroborating sensors within tolerance?).
Each design control is documented in the Software Design Document with an explicit cross-reference to the SSR it implements. The design review process includes a verification that each SSR has an identified design control, and each design control is justified as adequate for the failure mode it addresses. Controls that are adequate for Marginal hazards may not be adequate for Critical ones — the adequacy argument must be specific to the consequence severity.
Safety verification evidence
Safety verification evidence is the set of records that demonstrate each SSR is correctly implemented in the delivered software. The evidence base must be sufficient for a qualified reviewer — the government safety engineer, the safety review board, or the risk acceptance authority — to conclude that the software behaves as the safety case claims. Evidence that is present but untraceable to SSRs, or traceable to SSRs but insufficient to demonstrate their implementation, does not close the safety case.
The primary evidence types for software safety verification are:
Safety-specific test cases. For each SSR, one or more test cases are derived that directly exercise the required behavior. The test cases are constructed from the SwHA failure modes: if the SwHA row identifies "spurious assertion of FIRE_COMMAND during SAFE mode" as a hazard cause, the corresponding test case applies the specific input conditions that would be required to trigger this behavior and verifies that the output is not asserted. Testing to absence of hazardous behavior is more demanding than testing to presence of correct behavior — the test engineer must reason about all input paths that could reach the safety function and confirm that none produces a hazardous output.
Code coverage for safety-critical modules. Coverage metrics provide confidence that the test suite exercises the code paths that implement the SSRs. The coverage target for safety-critical modules (Category I and II functions under the SCI) is typically 100% branch coverage as a minimum, with Modified Condition/Decision Coverage (MC/DC) required for functions that implement multi-condition authorization logic. A branch coverage report that shows untested branches in a safety-critical module is an open finding — either the untested branch is dead code that must be removed, or a test case is missing. Coverage data without a corresponding SSR traceability map does not constitute safety verification evidence — the evidence is in the connection between covered code and the SSRs that code implements. See also: software testing military systems for a full treatment of test methodology for defense programs.
Software FMEA. A software Failure Modes and Effects Analysis applies the FMEA methodology to software modules rather than hardware components. For each function in a safety-critical module, the FMEA records: the function's purpose, the failure modes (using the five canonical categories from the SwHA), the effect of each failure mode on the software output, the effect on the system hazard, the detection mechanism (watchdog, monitor, test, operator observation), and the compensating control in the design. Software FMEA is most valuable as a cross-check on the SwHA — if the FMEA identifies a failure mode with hazardous consequences that does not appear in the SwHA, either the SwHA has a gap or the FMEA has a false positive that must be adjudicated. Both outcomes improve the safety case.
Code review records. Peer review of safety-critical code using a safety-specific checklist generates evidence that qualified engineers have examined the implementation for compliance with SSRs and design controls. The checklist items should map directly to the design patterns required — "watchdog reset called on each cycle," "all inputs validated before use," "state machine has no undefined transitions." Review records identify defects found and their dispositions; a review with zero findings against a complex safety-critical module is either an indication of an exceptionally clean implementation or of an insufficiently rigorous review process, and the program safety engineer should be able to distinguish between the two.
Integrating these evidence types into the DevSecOps for defense pipelines requires that safety-critical test cases, coverage tools, and FMEA worksheets are configuration-controlled alongside the source code they verify. A test result without a configuration baseline that identifies exactly which version of the software was tested is not reproducible evidence and cannot be submitted in a Safety Data Package. Every evidence artifact requires a document number, a revision, a date, and a link to the software configuration item baseline it covers.
Safety case assembly and residual risk acceptance
The safety case is a structured argument that the delivered software system is acceptably safe for its intended use. It does not claim the software is defect-free or that all risk has been eliminated — such claims are not achievable and are not what MIL-STD-882E requires. It claims that: all reasonably foreseeable hazards have been identified; controls have been applied that reduce each hazard to an acceptable risk level; the controls have been verified to be correctly implemented; and the residual risks that remain after controls are applied have been reviewed and accepted by the appropriate authority.
The safety case document structure follows a claim-argument-evidence hierarchy. Goal Structuring Notation (GSN) is commonly used to visualize this hierarchy, though the notation is not required — the structure must be present whether or not it is expressed in GSN form. A typical top-level structure for a fire control system software safety case:
in [defined operational context]
A1: Argument over identified hazards:
all hazards are either eliminated, controlled,
or accepted as residual risk
G2: All Catastrophic hazards with software contribution
are controlled to HRI <= 9
E1: SwHA worksheet rev D (CDRL AA-012)
E2: SSR traceability matrix rev C (CDRL AA-014)
E3: Safety test report rev B (CDRL AA-019)
G3: All Critical hazards with software contribution
are controlled to HRI <= 13
E4: Software FMEA rev A (CDRL AA-021)
E5: Code review records (CDRL AA-022)
A2: Residual risks reviewed and accepted per SSPP
Section 4.3 authority matrix
E6: Signed HRDRs for hazards H-003, H-007, H-011
The Safety Data Package (SDP) is the collection of artifacts delivered to the program office as evidence for the safety case. Its contents are specified in the System Safety Program Plan as a list of CDRLs with delivery dates tied to program milestones. Typical SDP contents:
- System Safety Program Plan (SSPP)
- Preliminary Hazard Analysis (PHA) report
- Subsystem Hazard Analysis (SSHA) reports
- Software Hazard Analysis (SwHA) worksheets
- Software Safety Requirements (SSR) list and traceability matrix
- Software Safety Design Analysis (Task 206) reports
- Software FMEA worksheets
- Safety-critical software test cases and test results
- Code coverage reports for safety-critical modules
- Code review records for safety-critical modules
- Hazard Risk Decision Reports (HRDRs) for accepted residual risks
- Safety Assessment Report (SAR)
Residual risk acceptance is the formal act by which the risk acceptance authority acknowledges that a hazard has been controlled to a level that remains above the program's acceptable threshold, reviews the evidence that controls are adequate and correctly implemented, and accepts responsibility for the remaining risk. The Hazard Risk Decision Report is the instrument for this act. The HRDR describes the hazard, the controls applied, the residual HRI after controls, the evidence supporting the residual HRI assessment, and a recommendation. The appropriate authority signs the HRDR, converting it from a recommendation to a formal risk acceptance record.
The safety case is a living document. Every time the software is modified — requirements change, defects are corrected, interfaces evolve — the safety case must be reviewed to determine whether the change affects any hazard, SSR, design control, or evidence item. A change that increases the probability or severity of an accepted residual risk requires a new HRDR signed by the appropriate authority. A change that introduces a new hazard cause requires a SwHA update and potentially a new SSR. Configuration management of the safety case artifacts is therefore as important as configuration management of the source code — an outdated safety case that does not reflect the current software baseline is not a safety case at all.
The most common failure mode of software safety programs is not inadequate analysis — it is inadequate follow-through. The SwHA is performed, the SSRs are written, the design controls are implemented, and then test planning proceeds without a systematic connection between the SSRs and the test cases. The coverage data is collected without a map to the safety-critical modules. The FMEA is written after code review rather than before. The result is a collection of individually plausible artifacts that do not compose into a coherent argument. The safety case assembly task is where these disconnects become visible — and addressing them before program reviews, rather than during them, is the difference between a defensible safety program and an expensive rework cycle.