STD: Control Fail Rule (CONTROLFAIL)
Version: v1.0.0
Status: Draft
SRS Source: docusaurus/docs/srs/rules/rule-control-fail.md
Rule Name: CONTROL_FAIL
Domain: RULES-CONTROLFAIL
Overview
This document specifies tests for the CONTROL_FAIL rule using decision tables and test vectors. The rule propagates control well failures to patient wells, ensuring that runs with failed quality controls cannot produce valid patient results.
Rule Characteristics:
- Pure business logic (no UI)
- Run-level quality control enforcement
- Control well failure detection with mix-based exclusion
- Patient well error propagation
Test Method: TM-API (per Test Plan section 3.3 - Rules use automated API tests)
Verification Approach:
Rule verification is performed using data-driven test vectors. Each row in a decision table represents a complete verification scenario with defined inputs and expected outputs. This format enables exhaustive condition coverage while remaining concise and auditable.
Coverage Summary
| REQ ID | Title | Conditions | Test Vectors | Coverage | Gaps |
|---|
| REQ-RULES-CONTROLFAIL-001 | Mark Patient Wells on Control Failure | 8 | 14 | 100% | None |
| REQ-RULES-CONTROLFAIL-002 | Exclude Unknown Mix Wells | 6 | 13 | 100% | None |
Totals: 2 REQs, 14 Conditions, 27 Test Vectors, 100% Coverage
| Variable | Type | Valid Values | Description |
|---|
run.control_wells | array | [] or [well...] | Control wells in the run |
control.status | enum | PASSED, FAILED | Control well pass/fail status |
control.mix_status | enum | known, unknown | Whether well mix is identifiable |
run.patient_wells | array | [well...] | Patient wells in the run |
Output Variables
| Variable | Type | Description |
|---|
patient.error_code | string? | QC error code (null if no error) |
patient.has_qc_error | bool | Whether patient well marked with error |
REQ-RULES-CONTROLFAIL-001: Mark Patient Wells on Control Failure
Decision Table: Core Control Failure Detection
| TV | control_count | any_control_failed | all_known_mix | patient_marked | Covers |
|---|
| TV-001-001 | 1 | true | true | true | AC: Single control failure triggers error |
| TV-001-002 | 1 | false | true | false | AC: No failure means no error |
| TV-001-003 | 3 | true (1 of 3) | true | true | AC: Single failure sufficient among multiple |
| TV-001-004 | 3 | true (all) | true | true | AC: Multiple failures still trigger |
| TV-001-005 | 3 | false | true | false | AC: All controls pass means no error |
Decision Table: No Control Wells Scenario
| TV | control_count | patient_count | patient_marked | Covers |
|---|
| TV-001-006 | 0 | 1 | false | EH: No controls in run, no error |
| TV-001-007 | 0 | 3 | false | EH: No controls, multiple patients unaffected |
Decision Table: Error Code Assignment
| TV | control_failed | error_code_assigned | error_type | Covers |
|---|
| TV-001-008 | true | true | QC_ERROR | AC: Error expressed as code |
| TV-001-009 | true | true | INHERITED_CONTROL_FAILURE | AC: Code indicates repeat due to QC |
Decision Table: All Patient Wells Affected
| TV | control_failed | patient_count | patients_marked | Covers |
|---|
| TV-001-010 | true | 5 | 5 | AC: All patient wells receive error |
Decision Table: Gap Coverage — Control Failure Propagation
| TV | Scenario | control_failed | patient_count | patient_marked | Covers |
|---|
| TV-CONTROLFAIL-GAP-006 | All known-mix controls failed | true (all) | 1 | true | AC: All known controls fail triggers error |
| TV-CONTROLFAIL-GAP-007 | Multiple patient wells all get error from failed controls | true (all) | 2 | true (all) | AC: Error propagated to all patients |
| TV-CONTROLFAIL-GAP-008 | No control wells in run — MINEXTRACT fires | 0 controls | 1 | MINEXTRACT error | EH: Missing controls produce different error |
| TV-CONTROLFAIL-GAP-009 | Single passing control set + single patient — minimal passing case | false | 1 | false | AC: Minimal passing scenario |
REQ-RULES-CONTROLFAIL-002: Unknown Mix Exclusion
Decision Table: Mix Status Filtering
| TV | control.status | control.mix_status | counted_as_failure | Covers |
|---|
| TV-002-001 | FAILED | known | true | AC: Known-mix failures counted |
| TV-002-002 | FAILED | unknown | false | AC: Unknown-mix excluded from count |
| TV-002-003 | PASSED | known | false | AC: Passed wells not failures |
| TV-002-004 | PASSED | unknown | false | AC: Passed unknown not failures |
Decision Table: Combined Scenarios
| TV | known_failed | unknown_failed | known_passed | unknown_passed | patient_marked | Covers |
|---|
| TV-002-005 | 0 | 1 | 1 | 0 | false | AC: Only unknown failures, no patient error |
| TV-002-006 | 1 | 1 | 0 | 0 | true | AC: Known failure present, patient marked |
| TV-002-007 | 0 | 0 | 1 | 1 | false | AC: All passed, no errors |
| TV-002-008 | 1 | 0 | 0 | 1 | true | AC: Known failure triggers despite unknown passed |
Decision Table: Gap Coverage — Unknown Mix Exclusion Scenarios
| TV | known_failed | unknown_failed | known_passed | unknown_passed | patient_marked | Covers |
|---|
| TV-CONTROLFAIL-GAP-001 | 0 | 0 | 1 | 1 (unrecognised) | false | AC: Unknown-mix control fails, patient NOT marked |
| TV-CONTROLFAIL-GAP-002 | 0 | 1 | 1 | 0 | false | AC: Extraction controls pass + unknown fails — patient clean |
| TV-CONTROLFAIL-GAP-003 | 0 | 0 | 1 | 0 | false | AC: Nonsense-label patient with known controls passing |
| TV-CONTROLFAIL-GAP-004 | 0 | 4 | 1 | 0 | false | AC: Many unknown-mix fails + passing extraction — no patient error |
| TV-CONTROLFAIL-GAP-005 | 0 | 3 | 1 | 0 | false | AC: Known-pass + many unknown-fail — patient clean |
Boundary Conditions
Decision Table: Edge Cases
| TV | Scenario | control_wells | result | Covers |
|---|
| TV-BND-001 | Single control, single patient | [C1:FAILED,known] | P1 marked | REQ-001 minimum case |
| TV-BND-002 | Many controls, all unknown-failed | [C1:FAILED,unknown, C2:FAILED,unknown] | P1 not marked | REQ-002 all-unknown edge |
| TV-BND-003 | Mixed: 1 known-pass, many unknown-fail | [C1:PASSED,known, C2:FAILED,unknown, C3:FAILED,unknown] | P1 not marked | REQ-002 pass dominates |
| TV-CONTROLFAIL-VARIANT-BND-PASS | Single control set passes + single patient — minimum viable passing | [C1:PASSED,known, C2:PASSED,known] | P1 not marked | REQ-001 minimum passing case |
Test File Locations
| Requirement | Test File | Automation Status |
|---|
| REQ-RULES-CONTROLFAIL-001 | tests/Unit/Rules/ControlFailRuleTest.php | Automated |
| REQ-RULES-CONTROLFAIL-002 | tests/Unit/Rules/ControlFailRuleTest.php | Automated |
Traceability to Existing Tests
| Requirement | Jira Tests | Status |
|---|
| REQ-RULES-CONTROLFAIL-001 | BT-2398 | Existing |
| REQ-RULES-CONTROLFAIL-002 | BT-2398 | Existing |
Gap Analysis
Identified Gaps
| Gap | Requirement | Description | Priority | Owner |
|---|
| None | - | Full coverage achieved | - | - |
No gaps identified. All acceptance criteria are covered by test vectors.