Skip to main content
Version: 3.0.0

Outcome Determination Rules Design

Document Type: Rule Design (Tier 2) Domain: RULES-OUTCOME Domain Character: Algorithmic Status: Draft Last Updated: 2026-01-25


1. Overview

1.0 Rule Summary

PropertyValue
IntentDetermine final well and target outcomes through sigmoid curve validation, combined outcome matching, and control well quality checks. This rule group evaluates PCR amplification patterns, assigns LIMS outcomes, and propagates control failures to patient wells.
InputsWell observations (readings, classification, CT, role), sigmoid curve direction, combined outcome configurations, control well statuses, mix configurations
OutputsLIMS outcome codes, error codes (well and target level), classification discrepancy flags, QC failure propagation
PrecedenceAfter classification rules (WDCLS/WDCT); before RQUAL fallback assignment

1.1 Purpose

The Outcome Determination Rules evaluate well observation results to assign final outcomes. This rule group encompasses:

  1. Sigmoid Curve Validation - Validates that curve shape matches classification polarity
  2. Combined Outcome Matching - Maps observation attributes to configured LIMS outcomes
  3. Control Well QC - Validates positive/negative control wells and propagates failures

These rules ensure that PCR analysis results are internally consistent and that quality control failures properly invalidate affected patient results.

1.2 Requirements Covered

REQ IDTitlePriority
REQ-RULES-COMBOUTCTRL-001Combined Outcome Control MatchingMust
REQ-RULES-SWCOMBOUT-001Single Well Combined Outcome AssignmentMust
REQ-RULES-MWCOMBOUT-001Multiple Wells Combined Outcome AssignmentMust
REQ-RULES-POSSIGMOID-001Positive Well Sigmoid ValidationMust
REQ-RULES-POSSIGMOID-002Positive Sigmoid Resolution SkipMust
REQ-RULES-POSSIGMOID-003Positive Sigmoid Manual SkipMust
REQ-RULES-NEGSIGMOID-001Negative Well Sigmoid ValidationMust
REQ-RULES-NEGSIGMOID-002Negative Sigmoid Resolution SkipMust
REQ-RULES-NEGSIGMOID-003Negative Sigmoid Manual SkipMust
REQ-RULES-DSIGMOID-001Downward Sigmoid Positive ValidationMust
REQ-RULES-DSIGMOID-002Downward Sigmoid Negative ValidationMust
REQ-RULES-DSIGMOID-003Downward Sigmoid Ambiguous ExclusionMust
REQ-RULES-DSIGMOID-004Downward Sigmoid Override ExclusionMust
REQ-RULES-DSIGMOID-005Classification Discrepancy FlagMust
REQ-RULES-POSSIGMOIDCTRL-001Positive Sigmoid Control ValidationMust
REQ-RULES-POSSIGMOIDCTRL-002Positive Sigmoid Control DisplayShould
REQ-RULES-NEGSIGMOIDCTRL-001Negative Sigmoid Control ValidationMust
REQ-RULES-NEGSIGMOIDCTRL-002Negative Sigmoid Control Patient ExclusionMust
REQ-RULES-NEGSIGMOIDCTRL-003Negative Sigmoid Control Resolution SkipMust
REQ-RULES-NEGSIGMOIDCTRL-004Negative Sigmoid Control Manual SkipMust
REQ-RULES-NEGSIGMOIDCTRL-005Negative Sigmoid Control DisplayShould
REQ-RULES-DSIGMOIDCTRL-001Sigmoid Control EvaluationMust
REQ-RULES-DSIGMOIDCTRL-002Sigmoid Control Error ReportingShould
REQ-RULES-WDCLSINVSIG-001WDCLS Invert Sigmoid SkipMust
REQ-RULES-WDCLSINVSIG-002WDCLS Invert CT Threshold SkipMust
REQ-RULES-WDCLSINVSIG-003WDCLS Invert Fluorescence SkipMust
REQ-RULES-WDCLSCINVSIG-001WDCLSC Invert Sigmoid SkipMust
REQ-RULES-WDCLSCINVSIG-002WDCLSC Invert CT Threshold SkipMust
REQ-RULES-WDCLSCINVSIG-003WDCLSC Invert Fluorescence SkipMust
REQ-RULES-CONTROLFAIL-001Control Failure Patient MarkingMust
REQ-RULES-CONTROLFAIL-002Unknown Mix ExclusionMust
REQ-RULES-NEC-001Negative Control ValidationMust
REQ-RULES-BPEC-001Positive Control ValidationMust
REQ-RULES-CC-001Curve Control CT BoundsMust
REQ-RULES-CC-002Curve Control Missing ConfigMust

1.3 Constraints

Tier 2 Constraint: This document describes design patterns and decision logic. It links to reference docs for configuration schemas.

1.4 Rule Categories

CategoryRulesPurpose
Sigmoid ValidationPOSITIVE_SIGMOID, NEGATIVE_SIGMOID, SIGMOID, SIGMOID_CONTROLValidate curve shape vs classification
Sigmoid ControlPOSITIVE_SIGMOID_CONTROL, NEGATIVE_SIGMOID_CONTROLSigmoid validation for control wells only
Invert SigmoidWDCLS_INVERT_SIGMOID_POS, WDCLSC_INVERT_SIGMOID_POSSkip discrepancy when sigmoid pattern explains difference
Combined OutcomesCOMBINED_OUTCOME_CONTROL, SINGLE_WELL_COMBINED_OUTCOME, MULTIPLE_WELLS_COMBINED_OUTCOMEMap observations to LIMS outcomes
Control QCBNC (NEC), BPEC, BCC, CONTROL_FAILValidate control wells and propagate failures

1.5 Dependencies


2. Component Architecture

2.1 Component Diagram

2.2 Component Responsibilities

ComponentFileResponsibilityREQ Trace
PositiveSigmoidRuleAnalyzer/Rules/PositiveSigmoidRule.phpValidate positive wells have upward sigmoidREQ-POSSIGMOID-*
NegativeSigmoidRuleAnalyzer/Rules/NegativeSigmoidRule.phpValidate negative wells have downward sigmoidREQ-NEGSIGMOID-*
SigmoidControlRuleAnalyzer/Rules/SigmoidControlRule.phpSigmoid validation with classification problem supportREQ-DSIGMOIDCTRL-*
SigmoidIdentifierSupport/SigmoidIdentifier.phpDetermine sigmoid direction from readingsAll sigmoid rules
WdclsInvertSigmoidPosRuleAnalyzer/Rules/WdclsInvertSigmoidPosRule.phpSkip CLS discrepancy for valid invert patternsREQ-WDCLSINVSIG-*
WdclscInvertSigmoidPosRuleAnalyzer/Rules/WdclscInvertSigmoidPosRule.phpSkip CLS discrepancy for control wellsREQ-WDCLSCINVSIG-*
CombinedOutcomeControlRuleAnalyzer/Rules/CombinedOutcomeControlRule.phpMatch outcomes with role verificationREQ-COMBOUTCTRL-001
SingleWellCombinedOutcomeRuleAnalyzer/Rules/SingleWellCombinedOutcomeRule.phpAssign outcomes for single-mix configurationsREQ-SWCOMBOUT-001
MultipleWellsCombinedOutcomeRuleAnalyzer/Rules/MultipleWellsCombinedOutcomeRule.phpCross-well patient matchingREQ-MWCOMBOUT-001
BncRuleAnalyzer/Rules/BncRule.phpValidate negative controls are negativeREQ-NEC-001
BpecRuleAnalyzer/Rules/BpecRule.phpValidate positive controls are positiveREQ-BPEC-001
BccRuleAnalyzer/Rules/BccRule.phpValidate CT within control boundsREQ-CC-*
ControlFailRuleAnalyzer/Rules/ControlFailRule.phpPropagate control failures to patientsREQ-CONTROLFAIL-*

3. Data Design

3.1 Entities

This rule group reads from well/observation data and writes to well error codes:

EntityOwnerRead/WriteFields Used
wellsRUNRPTRead/Writetype, error_code, lims_outcome, resolution_code, mix_id
observationsRUNRPTRead/Writereadings, final_cls, manual_cls, final_ct, problems, error_code
combined_outcomesKITCFGReadrole, type, mix_results, target_results
control_range_settingsKITCFGReadupper_bound, lower_bound, role_to_target_mapping

3.2 Sigmoid Direction Determination

interface SigmoidResult {
direction: 'upward' | 'downward' | 'not_sigmoid';
middle_index: number;
penultimate_index: number;
middle_value: number;
penultimate_value: number;
}

// For readings array of length n:
// middle_index = floor(n / 2)
// penultimate_index = n - 2
// upward: middle_value < penultimate_value
// downward: middle_value > penultimate_value
// not_sigmoid: middle_value == penultimate_value OR n < 4

3.3 Error Code Registry

Rule CategoryWell ErrorTarget Error
Positive SigmoidINCORRECT_POSITIVE_SIGMOIDINCORRECT_POSITIVE_SIGMOID_TARGET
Negative SigmoidINCORRECT_NEGATIVE_SIGMOIDINCORRECT_NEGATIVE_SIGMOID_TARGET
Downward SigmoidINCORRECT_SIGMOID-
NEC ValidationNEC_FAILURE_WELLNEC_FAILURE_TARGET
BPEC ValidationFAILED_POS_WELLFAILED_POS_TARGET
BCC - HighCONTROL_OUT_OF_RANGE_HIGH_WELLCONTROL_OUT_OF_RANGE_HIGH_TARGET
BCC - LowCONTROL_OUT_OF_RANGE_LOW_WELLCONTROL_OUT_OF_RANGE_LOW_TARGET
BCC - ConfigCC_LIMITS_MISSED-
Control FailINHERITED_CONTROL_FAILURE-

4. Interface Design

4.1 Rule Interface

All outcome rules implement the standard rule interface:

interface RuleInterface {
public function execute(Well $well, Kit $kit): void;
public function getName(): string;
public function getPrecedence(): int;
}

4.2 Sigmoid Identifier API

class SigmoidIdentifier {
public function identify(array $readings): SigmoidResult;
public function isUpward(array $readings): bool;
public function isDownward(array $readings): bool;
}

5. Behavioral Design

5.1 Sigmoid Validation Algorithm

Algorithm: Validate Sigmoid Curve Direction

Inputs:
- well: Well - The well being evaluated
- observation: Observation - Contains readings and classification
- expected_direction: 'upward' | 'downward' - Expected sigmoid for this classification

Outputs:
- void (modifies well.error_code, target.error_code)

Assumptions:
- Observation has readings array with at least 4 values
- Classification has been determined (final_cls available)
- Resolution codes and manual classifications are accessible

Steps:
1. Check skip conditions:
a. IF observation has manual_cls assigned: RETURN (no error)
b. IF well has matching resolution_code: RETURN (no error)

2. Check classification scope:
a. IF final_cls is null OR final_cls == 'Amb': RETURN (no error)
b. IF final_cls does not match rule target polarity: RETURN (no error)

3. Determine sigmoid direction:
a. IF readings.length < 4: RETURN (insufficient data)
b. middle_index = floor(readings.length / 2)
c. penultimate_index = readings.length - 2
d. IF readings[middle_index] > readings[penultimate_index]: direction = 'downward'
e. ELSE IF readings[middle_index] < readings[penultimate_index]: direction = 'upward'
f. ELSE: RETURN (not a sigmoid)

4. Validate direction:
a. IF direction != expected_direction:
- Set well.error_code = INCORRECT_{polarity}_SIGMOID
- Set target.error_code = INCORRECT_{polarity}_SIGMOID_TARGET
- Set observation.classification_discrepancy_flag = true

Notes:
- POSITIVE_SIGMOID rule expects upward sigmoid for positive classification
- NEGATIVE_SIGMOID rule expects downward sigmoid for negative classification
- Resolution code value matches rule name (e.g., POSITIVE_SIGMOID, NEGATIVE_SIGMOID)

5.1.1 Sigmoid Direction Decision Logic

Sigmoid DirectionClassificationError Assigned?
UpwardPositiveNo (valid)
UpwardNegativeYes (INCORRECT_NEGATIVE_SIGMOID)
DownwardPositiveYes (INCORRECT_POSITIVE_SIGMOID)
DownwardNegativeNo (valid)
Not SigmoidAnyNo (insufficient data)
*Amb/NullNo (excluded)

Precedence: Skip conditions evaluated first, then classification scope, then sigmoid direction. Default: If sigmoid cannot be determined, no error is assigned. Unreachable: None.

5.1.2 Skip Condition Decision Logic

Has Manual CLSHas Resolution CodeRule Executes?
Yes*No
NoYes (matching)No
NoNo/OtherYes

Precedence: Manual classification checked before resolution code. Default: Rule executes if no skip condition is met. Unreachable: None.

5.2 Control Sigmoid Validation (Control Wells Only)

Algorithm: Validate Sigmoid for Control Wells

Inputs:
- well: Well - The control well being evaluated
- observation: Observation - Contains readings and classification

Outputs:
- void (modifies well.error_code, target.error_code)

Assumptions:
- Well type is Control (not Patient)
- Same sigmoid determination algorithm applies

Steps:
1. Check well type:
a. IF well.type == 'Patient': RETURN (no error - excluded)

2. Check skip conditions:
a. IF observation has manual_cls assigned: RETURN (no error)
b. IF well has matching resolution_code: RETURN (no error)

3. Determine sigmoid direction (same as §5.1)

4. Validate direction vs classification:
a. POSITIVE_SIGMOID_CONTROL: downward + positive = error
b. NEGATIVE_SIGMOID_CONTROL: upward + negative = error

5. Assign errors if validation fails:
- POSITIVE_SIGMOID_CONTROL: INCORRECT_POSITIVE_SIGMOID, INCORRECT_POSITIVE_SIGMOID_TARGET
- NEGATIVE_SIGMOID_CONTROL: INCORRECT_NEGATIVE_SIGMOID, INCORRECT_NEGATIVE_SIGMOID_TARGET

Notes:
- Patient wells are explicitly excluded from control sigmoid rules
- Error display in Assay Summary grouped by Mix and Target

5.2.1 Control Sigmoid Decision Logic (POSITIVE_SIGMOID_CONTROL)

Well TypeSigmoidClassificationError?
Patient**No (excluded)
ControlUpwardPositiveNo (valid)
ControlUpwardNegativeNo
ControlDownwardPositiveYes
ControlDownwardNegativeNo (valid)

Precedence: Well type checked first; patient wells never produce errors. Default: Control wells with upward sigmoid + positive or downward + negative pass. Unreachable: None.

5.2.2 Control Sigmoid Decision Logic (NEGATIVE_SIGMOID_CONTROL)

Well TypeSigmoidClassificationError?
Patient**No (excluded)
ControlUpwardPositiveNo
ControlUpwardNegativeYes
ControlDownwardPositiveNo
ControlDownwardNegativeNo (valid)

Precedence: Well type checked first. Default: No error for valid patterns. Unreachable: None.

5.3 Invert Sigmoid Skip Logic

Algorithm: Skip CLS Discrepancy for Valid Invert Pattern

Inputs:
- observation: Observation - Contains readings, classification, CT
- target: Target - Contains threshold configurations
- is_control: bool - Whether this is a control well

Outputs:
- bool - Whether to skip the discrepancy error

Assumptions:
- A CLS discrepancy exists (DXAI cls != machine cls)
- Minimum fluorescence check passed

Steps:
1. Check minimum fluorescence:
a. IF max(readings) < minimum_fluorescence_to_positive: SKIP RULE ENTIRELY

2. Determine sigmoid direction

3. Check sigmoid + classification pattern:
a. IF direction == 'downward' AND final_cls == 'negative': SKIP ERROR
b. ELSE: Continue to CT check

4. Check CT threshold:
a. IF max_ct_for_cls_discrepancy is null: APPLY ERROR
b. IF final_ct >= max_ct_for_cls_discrepancy: SKIP ERROR
c. ELSE: APPLY ERROR

Notes:
- Downward sigmoid + negative classification is a valid invert pattern
- This indicates the sample is truly negative despite DXAI/machine disagreement
- CT threshold skip applies to high-cycle results where reliability decreases

5.3.1 Invert Sigmoid Decision Logic

Min FL Met?SigmoidClassificationCT >= Max?Result
No***Skip rule entirely
YesDownwardNegative*Skip discrepancy error
YesDownwardPositive*Apply discrepancy error
YesUpwardNegative*Apply discrepancy error
YesUpwardPositive*Apply discrepancy error
Yes**Yes (config set)Skip discrepancy error
Yes**NoApply discrepancy error

Precedence: Minimum fluorescence -> Sigmoid pattern -> CT threshold. Default: Apply discrepancy error if no skip condition met. Unreachable: None.

5.4 Combined Outcome Control Matching

Algorithm: Match Combined Outcome with Role Verification

Inputs:
- well: Well - The well being evaluated
- observation: Observation - Contains role, classification, CT, quantity, problems
- combined_outcome: CombinedOutcome - Configuration to match against

Outputs:
- void (modifies well.lims_outcome, well.error_code, target.error_code)

Steps:
1. Role verification (gate):
a. IF combined_outcome.role != observation.role: SKIP (no match)

2. Result matching:
a. IF target_result.result == 'Any': match = true
b. ELSE IF target_result.result == 'Classification/Discrepancy':
match = 'CLASSIFICATION' IN observation.problems
c. ELSE: match = (target_result.result == observation.final_cls)
d. IF NOT match: SKIP

3. Range checks:
a. IF configured AND NOT in_range(final_ct, min_ct, max_ct): SKIP
b. IF configured AND NOT in_range(quantity, min_quant, max_quant): SKIP

4. All targets check:
a. All target_results must be satisfied (AND logic)
b. IF any target fails: SKIP this outcome

5. Apply outcome:
a. IF combined_outcome.type == 'error':
- Set well.error_code = combined_outcome.well_error_code
- Set well.lims_outcome = null
- IF target_error configured: Set run_target.error_code
b. ELSE:
- Set well.lims_outcome = combined_outcome.lims_code

5.4.1 Combined Outcome Result Matching

Config ResultObservationCLASSIFICATION ProblemMatch?
Any**Yes
Classification/Discrepancy*YesYes
Classification/Discrepancy*NoNo
"Pos"Pos*Yes
"Pos"Neg*No
"Neg"Neg*Yes
"Neg"Pos*No

Precedence: Role -> Result -> CT/Qty ranges (all AND logic). Default: No match if any condition fails. Unreachable: None.

5.5 Single vs Multiple Well Combined Outcomes

Algorithm: Route Combined Outcome by Mix Count

Inputs:
- combined_outcome: CombinedOutcome - Configuration with mix_results
- well: Well - The well being evaluated

Outputs:
- bool - Whether outcome was assigned

Steps:
1. Count mix results:
mix_count = combined_outcome.mix_results.length

2. Route by count:
a. IF mix_count == 1: Use SingleWellCombinedOutcomeRule
b. IF mix_count >= 2: Use MultipleWellsCombinedOutcomeRule

Notes:
- Single-mix outcomes apply directly to the well
- Multi-mix outcomes require cross-well patient matching
- Wells not matched by single-mix remain eligible for multi-mix

5.5.1 Mix Count Routing Decision

Mix Results CountRule Applied
1SingleWellCombinedOutcomeRule
2+MultipleWellsCombinedOutcomeRule

Precedence: Single-well rules evaluate first; multi-well as fallback. Default: Well remains unassigned if no outcome matches. Unreachable: None (count >= 1 always true if outcome exists).

5.6 Control Well QC Validation

Algorithm: Validate Control Well QC

Inputs:
- well: Well - Control well being validated
- control_type: 'NEC' | 'NEG' | 'PEC' | 'POS' - Control well type
- observation: Observation - Contains classification and CT

Outputs:
- void (modifies well.error_code, target.error_code)

Steps:
1. NEC/NEG Validation (BNC rule):
a. IF well.type IN ['NEC', 'NEG']:
- IF observation.final_cls == 'positive':
- Set NEC_FAILURE_WELL on well
- Set NEC_FAILURE_TARGET on target

2. PEC Validation (BPEC rule):
a. IF well.type IN ['PEC', 'POS']:
- IF observation.final_cls == 'negative':
- Set FAILED_POS_WELL on well
- Set FAILED_POS_TARGET on target

3. Curve Control Validation (BCC rule):
a. IF control_range_setting not found for role-to-target:
- Set CC_LIMITS_MISSED on well
- RETURN
b. IF observation.final_cls != 'positive':
- Set FAILED_POS_WELL on well
- Set FAILED_POS_TARGET on target
- RETURN
c. IF final_ct > upper_bound:
- Set CONTROL_OUT_OF_RANGE_HIGH_WELL on well
- Set CONTROL_OUT_OF_RANGE_HIGH_TARGET on target
d. IF final_ct < lower_bound:
- Set CONTROL_OUT_OF_RANGE_LOW_WELL on well
- Set CONTROL_OUT_OF_RANGE_LOW_TARGET on target

5.6.1 NEC Validation Decision Logic

Well TypeClassificationError?
NECNegativeNo
NECPositiveYes (NEC_FAILURE)
NEGNegativeNo
NEGPositiveYes (NEC_FAILURE)
Other*No (not applicable)

Precedence: Well type checked first. Default: Non-control wells are not evaluated. Unreachable: None.

5.6.2 BCC Validation Decision Logic

Config Exists?ClassificationCT vs BoundsError?
No**CC_LIMITS_MISSED
YesNegative*FAILED_POS
YesPositive> upperCONTROL_OUT_OF_RANGE_HIGH
YesPositive< lowerCONTROL_OUT_OF_RANGE_LOW
YesPositiveIn boundsNo

Precedence: Config -> Classification -> Upper bound -> Lower bound. Default: Pass if all checks pass. Unreachable: None.

5.7 Control Failure Propagation

Algorithm: Propagate Control Failures to Patient Wells

Inputs:
- run: Run - Contains all wells
- patient_well: Well - Patient well being evaluated

Outputs:
- void (modifies patient_well.error_code)

Assumptions:
- Control wells have been validated by NEC/BPEC/BCC rules
- Well type and mix status are determined

Steps:
1. Get all control wells in run:
control_wells = run.wells.where(type = 'Control')

2. Filter by mix status:
known_mix_controls = control_wells.where(mix != 'unknown')

3. Check for failures:
failed_controls = known_mix_controls.where(has_failure = true)

4. Propagate if failures exist:
IF failed_controls.length > 0:
patient_well.error_code = INHERITED_CONTROL_FAILURE

Notes:
- Only control wells with known mixes count as failures
- Unknown mix wells are excluded to prevent false positives
- A single control failure invalidates all patient wells in the run

5.7.1 Control Failure Propagation Decision Logic

Any Known-Mix Control Failed?Patient Well Gets Error?
NoNo
YesYes (INHERITED_CONTROL_FAILURE)

Precedence: Unknown-mix controls are filtered out before failure check. Default: No error if no known-mix controls have failed. Unreachable: None.


6. Error Handling

ConditionDetectionResponseFallback
Insufficient readingsreadings.length < 4Skip sigmoid validationNo error assigned
Missing control range configrole-to-target lookup failsSet CC_LIMITS_MISSEDRule does not evaluate bounds
Missing classificationfinal_cls is nullSkip validation rulesAllow downstream rules
No matching combined outcomeEmpty matches listFall throughRQUAL rule handles
All controls have unknown mixknown_mix_controls.length == 0No failure propagationPatients unaffected

7. Configuration

SettingLocationDefaultEffectREQ
Resolution codesper-ruleRule nameBypass sigmoid validationPOSSIGMOID-002, NEGSIGMOID-002, etc.
minimum_fluorescence_to_positivetarget configRequiredSkip invert sigmoid ruleWDCLSINVSIG-003, WDCLSCINVSIG-003
max_ct_for_cls_discrepancytarget confignullSkip discrepancy at high CTWDCLSINVSIG-002, WDCLSCINVSIG-002
control_range.upper_boundper-mappingRequiredMax CT for curve controlCC-001
control_range.lower_boundper-mappingRequiredMin CT for curve controlCC-001
combined_outcome.roleoutcome configRequiredRole verification gateCOMBOUTCTRL-001
combined_outcome.typeoutcome config'outcome'error vs outcome behaviorCOMBOUTCTRL-001

8. Implementation Mapping

8.1 Code Locations

ComponentPath
Positive Sigmoidapp/Analyzer/Rules/PositiveSigmoidRule.php
Negative Sigmoidapp/Analyzer/Rules/NegativeSigmoidRule.php
Sigmoid Controlapp/Analyzer/Rules/SigmoidControlRule.php
Sigmoid Identifierapp/Support/SigmoidIdentifier.php
WDCLS Invert Sigmoidapp/Analyzer/Rules/WdclsInvertSigmoidPosRule.php
WDCLSC Invert Sigmoidapp/Analyzer/Rules/WdclscInvertSigmoidPosRule.php
Combined Outcome Controlapp/Analyzer/Rules/CombinedOutcomeControlRule.php
Single Well Combinedapp/Analyzer/Rules/SingleWellCombinedOutcomeRule.php
Multiple Wells Combinedapp/Analyzer/Rules/MultipleWellsCombinedOutcomeRule.php
Satisfies Combined Outcomeapp/Analyzer/Rules/Concerns/CombinedOutcomes/SatisfiesCombinedOutcome.php
Set Outcome to Wellapp/Analyzer/Rules/Concerns/CombinedOutcomes/SetOutcomeToWell.php
Check CLS Discrepancyapp/Analyzer/Rules/Concerns/CombinedOutcomes/CheckCLSDiscrepancy.php
Check CT Discrepancyapp/Analyzer/Rules/Concerns/CombinedOutcomes/CheckCTDiscrepancy.php
NEC Rule (BNC)app/Analyzer/Rules/BncRule.php
BPEC Ruleapp/Analyzer/Rules/BpecRule.php
BCC Ruleapp/Analyzer/Rules/BccRule.php
Control Fail Ruleapp/Analyzer/Rules/ControlFailRule.php
Set Error to Wellapp/Analyzer/Rules/Concerns/SetErrorToWell.php

8.2 Requirement Traceability

REQ IDDesign SectionPrimary Code
REQ-RULES-COMBOUTCTRL-001§5.4CombinedOutcomeControlRule.php
REQ-RULES-SWCOMBOUT-001§5.5SingleWellCombinedOutcomeRule.php
REQ-RULES-MWCOMBOUT-001§5.5MultipleWellsCombinedOutcomeRule.php
REQ-RULES-POSSIGMOID-001§5.1PositiveSigmoidRule.php
REQ-RULES-POSSIGMOID-002§5.1.2PositiveSigmoidRule.php
REQ-RULES-POSSIGMOID-003§5.1.2PositiveSigmoidRule.php
REQ-RULES-NEGSIGMOID-001§5.1NegativeSigmoidRule.php
REQ-RULES-NEGSIGMOID-002§5.1.2NegativeSigmoidRule.php
REQ-RULES-NEGSIGMOID-003§5.1.2NegativeSigmoidRule.php
REQ-RULES-DSIGMOID-001§5.1SigmoidRule.php
REQ-RULES-DSIGMOID-002§5.1SigmoidRule.php, NegativeSigmoidRule.php
REQ-RULES-DSIGMOID-003§5.1SigmoidRule.php
REQ-RULES-DSIGMOID-004§5.1.2SigmoidRule.php
REQ-RULES-DSIGMOID-005§5.1SigmoidRule.php
REQ-RULES-POSSIGMOIDCTRL-001§5.2PositiveSigmoidControlRule.php
REQ-RULES-POSSIGMOIDCTRL-002§5.2PositiveSigmoidControlRule.php
REQ-RULES-NEGSIGMOIDCTRL-001§5.2.2NegativeSigmoidControlRule.php
REQ-RULES-NEGSIGMOIDCTRL-002§5.2.1NegativeSigmoidControlRule.php
REQ-RULES-NEGSIGMOIDCTRL-003§5.1.2NegativeSigmoidControlRule.php
REQ-RULES-NEGSIGMOIDCTRL-004§5.1.2NegativeSigmoidControlRule.php
REQ-RULES-NEGSIGMOIDCTRL-005§5.2NegativeSigmoidControlRule.php
REQ-RULES-DSIGMOIDCTRL-001§5.2SigmoidControlRule.php
REQ-RULES-DSIGMOIDCTRL-002§5.2SigmoidControlRule.php
REQ-RULES-WDCLSINVSIG-001§5.3WdclsInvertSigmoidPosRule.php
REQ-RULES-WDCLSINVSIG-002§5.3.1WdclsInvertSigmoidPosRule.php
REQ-RULES-WDCLSINVSIG-003§5.3.1WdclsInvertSigmoidPosRule.php
REQ-RULES-WDCLSCINVSIG-001§5.3WdclscInvertSigmoidPosRule.php
REQ-RULES-WDCLSCINVSIG-002§5.3.1WdclscInvertSigmoidPosRule.php
REQ-RULES-WDCLSCINVSIG-003§5.3.1WdclscInvertSigmoidPosRule.php
REQ-RULES-CONTROLFAIL-001§5.7ControlFailRule.php
REQ-RULES-CONTROLFAIL-002§5.7.1ControlFailRule.php
REQ-RULES-NEC-001§5.6, §5.6.1BncRule.php
REQ-RULES-BPEC-001§5.6BpecRule.php
REQ-RULES-CC-001§5.6.2BccRule.php
REQ-RULES-CC-002§5.6.2BccRule.php

9. Design Decisions

DecisionRationaleAlternatives Considered
Separate sigmoid rules by polarityClearer error attribution, independent testingSingle unified rule (rejected: less precise errors)
Control wells excluded from patient sigmoid rulesDifferent validation requirements for controlsApply same rules to all (rejected: inappropriate for QC)
Invert sigmoid pattern recognized as validDownward sigmoid + negative = truly negative sampleTreat all discrepancies as errors (rejected: false positives)
Dual-level error codes (well + target)Traceability at both granularitiesWell-only errors (rejected: loses target context)
Unknown mix exclusion from control failurePrevent false positives from unidentifiable configsInclude all controls (rejected: configuration drift issues)
CT threshold for discrepancy skipLate-cycle results less reliableNo threshold (rejected: excessive false errors)

10. Performance Considerations

ScenarioConcernMitigation
Large runfiles (>384 wells)Control failure propagationEarly exit if no failures found
Many combined outcomes (>50)Matching iterationRole pre-filter, priority grouping
Sigmoid calculationArray operationsCache sigmoid direction per observation
Multi-mix patient matchingCross-well groupingIndex on accession, batch by patient

DocumentRelevant Sections
SRS: rule-combined-outcomes-control.mdCombined outcome control requirements
SRS: rule-positive-sigmoid.mdPositive sigmoid requirements
SRS: rule-negative-sigmoid.mdNegative sigmoid requirements
SRS: rule-downward-sigmoid.mdDownward sigmoid requirements
SRS: rule-wdcls-invert-sigmoid.mdWDCLS invert sigmoid requirements
SRS: rule-control-fail.mdControl failure requirements
SRS: rule-nec.mdNEC validation requirements
SRS: rule-bpec.mdBPEC validation requirements
SRS: rule-cc.mdCurve control requirements
SDS: Combined OutcomesDetailed combined outcome design
SDS: Rules EngineFramework overview