Classification Rules Design
Document Type: Rule Design (Tier 2) Domain: RULES-CLASSIFICATION Domain Character: Algorithmic Status: Draft Last Updated: 2026-01-25
1. Overview
1.0 Rule Summary
| Property | Value |
|---|---|
| Intent | Ensure classification integrity by detecting discrepancies between pcr.ai and machine classifications (CLS/CT), validating CT thresholds, handling ambiguous results, and enforcing consistency between target pairs. |
| Inputs | Observation data (final_cls, final_ct, machine_cls, machine_ct, readings), Target configuration (thresholds, cutoffs), Well type (Patient/Control) |
| Outputs | Error codes (CLSDISC_WELL, CTDISC_WELL, CONTROL_CLSDISC_*, BAD_CT_DELTA, etc.), Problem flags (CLASSIFICATION, CT_DISC), Classification updates |
| Precedence | After CT/CLS calculation, before Combined Outcomes; WDCLS before WDCT; WFINALCLS early in pipeline |
1.1 Purpose
The Classification Rules family ensures the integrity and consistency of PCR analysis results by:
- Discrepancy Detection - Identifying mismatches between pcr.ai and machine classifications/CT values
- Threshold Validation - Enforcing CT cutoffs and quantity boundaries
- Ambiguity Resolution - Handling indeterminate or ambiguous classification results
- Cross-Target Consistency - Validating CT relationships between configured target pairs
These rules are critical for laboratory quality control, flagging results that require manual review while maintaining audit trail integrity.
1.2 Requirements Covered
| REQ ID | Title | Priority | Rule |
|---|---|---|---|
| REQ-RULES-WDCLS-001 | Detect Classification Discrepancies | Must | WDCLS |
| REQ-RULES-WDCLS-002 | CT Threshold Suppression | Must | WDCLS |
| REQ-RULES-WDCLS-003 | Fluorescence Threshold Skip | Must | WDCLS |
| REQ-RULES-WDCLSC-001 | Control Well CLS Discrepancy | Must | WDCLSC |
| REQ-RULES-WDCLSC-002 | Control CT Threshold Exemption | Must | WDCLSC |
| REQ-RULES-WDCLSC-003 | Control Fluorescence Skip | Must | WDCLSC |
| REQ-RULES-WDCT-001 | Detect CT Discrepancies | Must | WDCT |
| REQ-RULES-WDCT-002 | CT Threshold Suppression | Must | WDCT |
| REQ-RULES-WDCT-003 | Fluorescence Threshold Skip | Must | WDCT |
| REQ-RULES-WDCTC-001 | Control CT Discrepancy | Must | WDCTC |
| REQ-RULES-WDCTC-002 | Control CT Threshold Suppression | Must | WDCTC |
| REQ-RULES-WDCTC-003 | Control Fluorescence Skip | Must | WDCTC |
| REQ-RULES-CTCUTOFF-001 | CT Cutoff Sets Negative | Must | WFINALCLS |
| REQ-RULES-CTCUTOFF-002 | Specimen-Based Reporting | Must | WFINALCLS |
| REQ-RULES-CTCUTOFF-003 | NULL CT Handling | Must | WFINALCLS |
| REQ-RULES-CTCUTOFF-004 | NULL Quantity Preservation | Must | WFINALCLS |
| REQ-RULES-CTCUTOFF-005 | Missing Config Error | Must | WFINALCLS |
| REQ-RULES-INDETCTS-001 | Indeterminate High CT Detection | Must | INDETERMINATE_CTS |
| REQ-RULES-THRESH-001 | Threshold Validation | Must | THRESHOLD |
| REQ-RULES-THRESH-002 | Error Persistence | Must | THRESHOLD |
| REQ-RULES-THRESH-003 | Missing Config Detection | Must | THRESHOLD |
| REQ-RULES-DELTACT-001 | Delta CT Validation | Must | DELTA_CT |
| REQ-RULES-AMB-001 | AMB Problem Assignment | Must | AMB |
| REQ-RULES-AMB-002 | AMB Visual Flagging | Should | AMB |
| REQ-RULES-AMB-003 | AMB Resolution Processing | Must | AMB |
| REQ-RULES-AMB-004 | AMB Manual Prevention | Must | AMB |
1.3 Constraints
Tier 2 Constraint: This document describes ownership, patterns, and design rationale. It links to reference docs for full schemas.
1.4 Rule Family Structure
1.5 Dependencies
| Direction | Component | Purpose |
|---|---|---|
| Consumes | Observation data | CLS, CT, readings, target |
| Target configuration | Thresholds, cutoffs | |
| Reporting configuration | Upper boundaries, specimen-based settings | |
| Produces | Error codes | Well-level and target-level errors |
| Problem flags | Observation-level issues | |
| Classification updates | Final CLS modifications | |
| Precedes | Combined Outcomes | Discrepancy flags used for matching |
| RQUAL | Fallback outcome assignment |
2. Component Architecture
2.1 Component Diagram
2.2 Component Responsibilities
| Component | File | Responsibility | REQ Trace |
|---|---|---|---|
WdclsRule | Analyzer/Rules/WdclsRule.php | Patient CLS discrepancy detection | WDCLS-001,002,003 |
WdclscRule | Analyzer/Rules/WdclscRule.php | Control CLS discrepancy detection | WDCLSC-001,002,003 |
WdctRule | Analyzer/Rules/WdctRule.php | Patient CT discrepancy detection | WDCT-001,002,003 |
WdctcRule | Analyzer/Rules/WdctcRule.php | Control CT discrepancy detection | WDCTC-001,002,003 |
WfinalclsRule | Analyzer/Rules/WfinalclsRule.php | CT cutoff classification | CTCUTOFF-001..005 |
ThresholdRule | Analyzer/Rules/ThresholdRule.php | Runfile threshold validation | THRESH-001,002,003 |
DeltaCtRule | Analyzer/Rules/DeltaCtRule.php | Target pair CT consistency | DELTACT-001 |
IndeterminateCtRule | Analyzer/Rules/IndeterminateCtRule.php | High CT indeterminate detection | INDETCTS-001 |
AmbRule | Analyzer/Rules/AmbRule.php | Ambiguous classification handling | AMB-001..004 |
ObservationClsDiscrepancyChecker | Concerns/.../Discrepancy/... | Reusable CLS discrepancy check | WDCLS, COMBOUT |
ObservationCtDiscrepancyChecker | Concerns/.../Discrepancy/... | Reusable CT discrepancy check | WDCT, COMBOUT |
SetErrorToWell | Concerns/SetErrorToWell.php | Apply error codes to wells | All |
3. Data Design
3.1 Entities
This rule family reads configuration and observation data, writes errors and problems:
| Entity | Owner | Read/Write | Fields Used |
|---|---|---|---|
observations | RUNRPT | Read/Write | final_cls, final_ct, machine_cls, machine_ct, readings, problems |
wells | RUNRPT | Read/Write | error_codes, resolution_codes, type |
targets | KITCFG | Read | thresholds, min_fluorescence_to_positive, max_ct_for_* |
reporting | KITCFG | Read | ct_upper_boundary, specimen_type |
delta_ct_combinations | KITCFG | Read | first_target_id, second_target_id, delta_ct |
3.2 Threshold Configuration
interface TargetThresholds {
max_ct_for_cls_discrepancy: number | null; // REQ-WDCLS-002
max_ct_for_ct_discrepancy: number | null; // REQ-WDCT-002
minimum_fluorescence_to_positive: number; // REQ-WDCLS-003, WDCT-003
ct_cutoff_threshold: number; // REQ-CTCUTOFF-001, default 40
indeterminate_ct_threshold: number; // REQ-INDETCTS-001, default 35
expected_threshold: number | null; // REQ-THRESH-001
}
3.3 Error Codes
| Error Code | Rule | Well Type | Meaning |
|---|---|---|---|
CLSDISC_WELL | WDCLS | Patient | CLS discrepancy detected |
CTDISC_WELL | WDCT | Patient | CT discrepancy detected (>2 cycles) |
CONTROL_CLSDISC_WELL | WDCLSC | Control | Control CLS discrepancy |
CONTROL_CLSDISC_TARGET | WDCLSC | Control | Target-level CLS discrepancy |
CONTROL_CTDISC_WELL | WDCTC | Control | Control CT discrepancy |
CONTROL_CTDISC_TARGET | WDCTC | Control | Target-level CT discrepancy |
CUTOFF_LIMITS_MISSED | WFINALCLS | Any | Missing cutoff configuration |
THRESHOLD_WRONG | THRESHOLD | Any | Threshold mismatch |
THRESHOLD_MISSED | THRESHOLD | Any | Missing threshold configuration |
BAD_CT_DELTA | DELTA_CT | Any | Target pair CT/CLS mismatch |
INDETERMINATE_CTS | INDETERMINATE_CTS | Any | All positive with high CT |
4. Interface Design
4.1 Rule Interface
All classification rules implement the standard AnalyzerRuleContract:
interface AnalyzerRuleContract {
public function handle(
ConfigurationRepository $config,
AnalyzableObservation $observation,
RunMix $runMix,
RunTarget $runTarget,
AnalyzableWell $well,
WellCollection $wells,
PatientWellCollection $previousPatientWells,
PecWellCollection $previousPecWells,
RunTargetsCollection $runTargets
): void;
}
4.2 Observation Interface
Key methods used by classification rules:
| Method | Returns | Purpose |
|---|---|---|
shouldCheckForClsDiscrepancy() | bool | Pre-conditions for CLS check |
shouldCheckForCtDiscrepancy() | bool | Pre-conditions for CT check |
hasDiscrepancyBetweenPreferredAndNonPreferredCls() | bool | CLS comparison |
hasLargeDiscrepancyBetweenPreferredAndNonPreferredCt() | bool | CT diff > 2 |
ctIsHigherThanMaxCTForClsDiscrepancy() | bool | CT threshold suppression |
ctIsHigherThanMaxCTForCtDiscrepancy() | bool | CT threshold suppression |
maxReadingIsLessThanTargetMinFl() | bool | Fluorescence threshold skip |
finalClsIsNegative() | bool | Classification check |
getFinalCt() | float | null |
getFinalCls() | string | Classification result |
addProblem(string $problem) | void | Flag observation |
setFinalCls(string $cls) | void | Update classification |
5. Behavioral Design
5.1 WDCLS Algorithm (REQ-WDCLS-001, 002, 003)
Algorithm: Well Discrepant Classification (Patient)
Inputs:
- observation: Observation - PCR results with classifications
- well: Well - The patient well being evaluated
- config: Configuration - Threshold settings
Outputs:
- void (modifies well.error_codes, observation.problems)
Assumptions:
- Well is Patient type (not Control)
- Both pcr.ai and machine classifications are available
- WFINALCLS has already executed
Steps:
1. Resolution check: IF well.resolution_codes contains 'WDCLS': apply LIMS status, RETURN
2. Discrepancy check skip: IF NOT observation.shouldCheckForClsDiscrepancy(): RETURN
3. Reporting boundary check:
IF observation.isFinalCtOrClsOverPassedReportingUpperBoundary() OR
observation.isBothMachineCtAndDxaiCtOverpassedReportingUpperBoundary():
RETURN
4. CT threshold suppression (REQ-WDCLS-002):
IF observation.ctIsHigherThanMaxCTForClsDiscrepancy():
RETURN (suppressed)
5. Fluorescence threshold skip (REQ-WDCLS-003):
IF observation.finalClsIsNegative() AND observation.maxReadingIsLessThanTargetMinFl():
RETURN (skipped)
6. Discrepancy detection (REQ-WDCLS-001):
IF observation.hasDiscrepancyBetweenPreferredAndNonPreferredCls():
SET well.error_code = 'CLSDISC_WELL'
ADD observation.problems = 'CLASSIFICATION'
Notes:
- Identical logic for WDCLSC but with CONTROL_CLSDISC_* error codes
- WDCLSC also sets target-level error
5.1.1 WDCLS Decision Logic
| Condition | max_ct_for_cls_discrepancy | final_ct | Result |
|---|---|---|---|
| Threshold null | null | any | Check discrepancy |
| CT >= threshold | 35 | 36 | Suppress (no error) |
| CT >= threshold | 36 | 36 | Suppress (no error) |
| CT < threshold | 37 | 36 | Check discrepancy |
Precedence: CT threshold evaluated before discrepancy check. Default: If threshold is null, no CT-based suppression applies.
5.1.2 Fluorescence Threshold Logic
min_fluorescence | max(readings) | final_cls | Result |
|---|---|---|---|
| 100 | 99 | Negative | Skip rule |
| 100 | 99 | Positive | Check discrepancy |
| 100 | 100 | any | Check discrepancy |
Precedence: Fluorescence evaluated after CT threshold. Note: Skip applies only when classification is Negative AND max reading is below threshold.
5.2 WDCT Algorithm (REQ-WDCT-001, 002, 003)
Algorithm: Well Discrepant CT (Patient)
Inputs:
- observation: Observation - PCR results with CT values
- well: Well - The patient well being evaluated
- config: Configuration - Threshold settings
Outputs:
- void (modifies well.error_codes, observation.problems)
Steps:
1. Resolution check: IF well.resolution_codes contains 'WDCT': apply LIMS status, RETURN
2. WDCLS resolution check: IF well.resolution_codes contains 'WDCLS': RETURN
3. Discrepancy check skip: IF NOT observation.shouldCheckForCtDiscrepancy(): RETURN
4. CT threshold suppression (REQ-WDCT-002):
IF observation.ctIsHigherThanMaxCTForCtDiscrepancy():
RETURN (suppressed)
5. CLS discrepancy priority:
IF well.hasError('CLSDISC_WELL'):
RETURN (CLS discrepancy takes precedence)
6. Fluorescence threshold skip (REQ-WDCT-003):
IF observation.finalClsIsNegative() AND observation.maxReadingIsLessThanTargetMinFl():
RETURN (skipped)
7. CT discrepancy detection (REQ-WDCT-001):
IF observation.hasLargeDiscrepancyBetweenPreferredAndNonPreferredCt():
SET well.error_code = 'CTDISC_WELL'
ADD observation.problems = 'CT_DISC'
Notes:
- CT discrepancy threshold is fixed at >2 cycles
- Classification must be non-negative for check to apply
- WDCLS error takes precedence (no CT error if CLS error exists)
5.2.1 CT Discrepancy Detection
pcr.ai_ct | machine_ct | abs(diff) | Result |
|---|---|---|---|
| 25.0 | 26.5 | 1.5 | No error |
| 25.0 | 27.0 | 2.0 | No error (not >2) |
| 25.0 | 27.1 | 2.1 | CTDISC_WELL error |
| 25.0 | 28.5 | 3.5 | CTDISC_WELL error |
Threshold: Fixed at >2 cycles (not configurable).
5.3 WFINALCLS Algorithm (REQ-CTCUTOFF-001..005)
Algorithm: CT Cutoff Classification
Inputs:
- observation: Observation - PCR results
- well: Well - The well being evaluated
- config: Configuration - Cutoff and reporting settings
Outputs:
- void (modifies observation.final_cls, well.error_codes)
Steps:
1. Resolution check: IF well.resolution_codes contains 'WFINALCLS': apply LIMS status, RETURN
2. Reporting lookup (REQ-CTCUTOFF-002, 005):
reporting = config.getFirstGroupReportingForObservation(observation)
IF reporting is null:
SET well.error_code = 'CUTOFF_LIMITS_MISSED'
RETURN
3. Upper boundary flagging:
IF observation.dxai_ct or cls > reporting.upper_boundary:
SET observation.dxai_ct_overpassed = true
IF observation.machine_ct or cls > reporting.upper_boundary:
SET observation.machine_ct_overpassed = true
4. Skip negative: IF observation.hasNegativeFinalCls(): RETURN
5. CT cutoff check (REQ-CTCUTOFF-001):
IF observation.final_ct > reporting.ct_upper_boundary OR
observation.final_ct IS NULL (REQ-CTCUTOFF-003):
SET observation.final_cls = 'Neg'
FLAG observation.ct_cls_overpassed = true
Notes:
- NULL CT treated as boundary exceeded (REQ-CTCUTOFF-003)
- NULL Quantity preserves classification (REQ-CTCUTOFF-004)
- Specimen-type matching when use_sample_type enabled (REQ-CTCUTOFF-002)
5.3.1 NULL Value Handling Truth Table
| Field | Value | Action | Rationale |
|---|---|---|---|
final_ct | NULL | Set Negative | Missing CT = measurement failure |
final_ct | 45 | Set Negative | Exceeds default cutoff (40) |
final_ct | 35 | Preserve | Within boundary |
quantity | NULL | Preserve | No classification change |
quantity | 0 | Evaluate boundary | Use configured limits |
5.4 DELTA_CT Algorithm (REQ-DELTACT-001)
Algorithm: Delta CT Validation
Inputs:
- observation: Observation - Current observation
- well: Well - Contains all observations
- config: Configuration - Delta CT combinations
Outputs:
- void (modifies well.error_codes)
Steps:
1. Configuration lookup:
combinations = config.getDeltaCtTargetCombinationsForTarget(observation.target)
IF combinations.isEmpty(): RETURN
2. For each combination in combinations:
a. Find pair observation in same well matching combination targets
b. IF no pair observation: CONTINUE (skip)
c. Threshold check:
delta = abs(observation.final_ct - pair.final_ct)
IF delta >= combination.delta_ct:
hasBadDelta = true
BREAK
d. Classification check:
IF observation.final_cls != pair.final_cls:
hasBadDelta = true
BREAK
3. Apply error:
IF hasBadDelta:
SET well.error_code = 'BAD_CT_DELTA'
Notes:
- Pair matching is bidirectional (A,B or B,A)
- Either CT delta OR classification mismatch triggers error
- IC targets excluded from validation
5.4.1 Delta CT Decision Logic
| Target A CLS | Target A CT | Target B CLS | Target B CT | Threshold | Result |
|---|---|---|---|---|---|
| Positive | 30 | Positive | 32 | 3 | No error (delta=2) |
| Positive | 30 | Positive | 33 | 3 | BAD_CT_DELTA (delta=3) |
| Positive | 30 | Positive | 34 | 3 | BAD_CT_DELTA (delta=4) |
| Positive | 30 | Negative | 30 | 3 | BAD_CT_DELTA (CLS mismatch) |
Precedence: Classification mismatch checked independently of CT delta. Operator: Uses >= for threshold comparison (boundary triggers error).
5.5 INDETERMINATE_CTS Algorithm (REQ-INDETCTS-001)
Algorithm: Indeterminate High CT Detection
Inputs:
- well: Well - The well being evaluated
- config: Configuration - Indeterminate threshold (default 35)
Outputs:
- void (modifies well.error_codes)
Steps:
1. Get non-IC observations: nonIcObs = well.getNonIcTargetObservations()
2. Check all positive with high CT:
IF nonIcObs.every(obs => obs.hasPositiveFinalCls() AND obs.final_ct > 35):
SET well.error_code = 'INDETERMINATE_CTS'
Notes:
- Rule fails only when ALL non-IC targets meet both conditions
- If any target is Negative or has CT <= 35, rule passes
- IC targets excluded from evaluation
5.5.1 Indeterminate Detection Truth Table
| Target A CLS | Target A CT | Target B CLS | Target B CT | Result |
|---|---|---|---|---|
| Positive | 36 | Positive | 37 | INDETERMINATE_CTS |
| Positive | 36 | Positive | 35 | Pass (B CT <= 35) |
| Positive | 36 | Negative | 38 | Pass (B is Negative) |
| Negative | 36 | Negative | 37 | Pass (neither Positive) |
5.6 AMB Algorithm (REQ-AMB-001..004)
Algorithm: Ambiguous Classification Handling
Inputs:
- observation: Observation - PCR results
- well: Well - The well being evaluated
Outputs:
- void (modifies observation.problems)
Steps:
1. Resolution check: IF well.resolution_codes contains 'AMB': RETURN
2. Ambiguity detection (REQ-AMB-001):
IF observation.hasAmbiguousFinalCls():
ADD observation.problems = 'CLASSIFICATION'
Notes:
- Resolution codes processed separately (REQ-AMB-003)
- Manual resolution blocked by system design (REQ-AMB-004)
- Visual flagging handled by UI layer (REQ-AMB-002)
5.6.1 AMB Resolution Code Processing
| Resolution Code | Action | final_cls | error_code | problems |
|---|---|---|---|---|
| AMB,SETPOS | Change to Positive | Pos | cleared | cleared |
| AMB,SETNEG | Change to Negative | Neg | cleared | cleared |
| AMB | Clear error only | Amb (unchanged) | cleared | cleared |
6. Error Handling
| Condition | Detection | Response | Fallback |
|---|---|---|---|
| Missing reporting config | null from lookup | CUTOFF_LIMITS_MISSED | Rule aborts |
| Missing threshold config | null from lookup | THRESHOLD_MISSED | Rule aborts |
| Threshold mismatch | Values differ | THRESHOLD_WRONG | Permanent error |
| CLS discrepancy on Patient | Classifications differ | CLSDISC_WELL | Flags for review |
| CLS discrepancy on Control | Classifications differ | CONTROL_CLSDISC_* | Target-level error |
| CT discrepancy (>2 cycles) | CT difference check | CTDISC_WELL | Flags for review |
| All positive high CT | All non-IC > 35 | INDETERMINATE_CTS | Flags for review |
| Target pair inconsistency | Delta CT >= threshold | BAD_CT_DELTA | Flags for review |
7. Configuration
| Setting | Rule | Path | Default | Effect |
|---|---|---|---|---|
max_ct_for_cls_discrepancy | WDCLS, WDCLSC | target.* | null | Suppress CLS discrepancy error |
max_ct_for_ct_discrepancy | WDCT, WDCTC | target.* | null | Suppress CT discrepancy error |
minimum_fluorescence_to_positive | WD* | target.* | - | Skip rule on low fluorescence |
ct_cutoff_threshold | WFINALCLS | reporting.* | 40 | CT upper boundary |
indeterminate_ct_threshold | INDETERMINATE_CTS | system | 35 | High CT threshold |
expected_threshold | THRESHOLD | mix.* | - | Runfile threshold validation |
delta_ct | DELTA_CT | combination.* | - | Target pair delta threshold |
use_sample_type | WFINALCLS | system | false | Enable specimen-based reporting |
See Configuration Reference for full documentation.
8. Implementation Mapping
8.1 Code Locations
| Component | Path |
|---|---|
| WDCLS Rule | app/Analyzer/Rules/WdclsRule.php |
| WDCLSC Rule | app/Analyzer/Rules/WdclscRule.php |
| WDCT Rule | app/Analyzer/Rules/WdctRule.php |
| WDCTC Rule | app/Analyzer/Rules/WdctcRule.php |
| WFINALCLS Rule | app/Analyzer/Rules/WfinalclsRule.php |
| Threshold Rule | app/Analyzer/Rules/ThresholdRule.php |
| Delta CT Rule | app/Analyzer/Rules/DeltaCtRule.php |
| Indeterminate CT Rule | app/Analyzer/Rules/IndeterminateCtRule.php |
| AMB Rule | app/Analyzer/Rules/AmbRule.php |
| CLS Discrepancy Checker | app/Analyzer/Rules/Concerns/CombinedOutcomes/Discrepancy/ObservationClsDiscrepancyChecker.php |
| CT Discrepancy Checker | app/Analyzer/Rules/Concerns/CombinedOutcomes/Discrepancy/ObservationCtDiscrepancyChecker.php |
| SetErrorToWell | app/Analyzer/Rules/Concerns/SetErrorToWell.php |
8.2 Requirement Traceability
| REQ ID | Design Section | Primary Code |
|---|---|---|
| REQ-RULES-WDCLS-001 | §5.1 | WdclsRule.php:66-70 |
| REQ-RULES-WDCLS-002 | §5.1, §5.1.1 | WdclsRule.php:58-60 |
| REQ-RULES-WDCLS-003 | §5.1, §5.1.2 | WdclsRule.php:62-64 |
| REQ-RULES-WDCLSC-001 | §5.1 | WdclscRule.php:63-68 |
| REQ-RULES-WDCLSC-002 | §5.1.1 | WdclscRule.php:55-57 |
| REQ-RULES-WDCLSC-003 | §5.1.2 | WdclscRule.php:59-61 |
| REQ-RULES-WDCT-001 | §5.2 | WdctRule.php:64-68 |
| REQ-RULES-WDCT-002 | §5.2 | WdctRule.php:52-54 |
| REQ-RULES-WDCT-003 | §5.2 | WdctRule.php:60-62 |
| REQ-RULES-WDCTC-001 | §5.2 | WdctcRule.php:64-68 |
| REQ-RULES-WDCTC-002 | §5.2 | WdctcRule.php:56-58 |
| REQ-RULES-WDCTC-003 | §5.2 | WdctcRule.php:60-62 |
| REQ-RULES-CTCUTOFF-001 | §5.3 | WfinalclsRule.php:64-67 |
| REQ-RULES-CTCUTOFF-002 | §5.3 | WfinalclsRule.php:46 |
| REQ-RULES-CTCUTOFF-003 | §5.3, §5.3.1 | WfinalclsRule.php:64 |
| REQ-RULES-CTCUTOFF-004 | §5.3.1 | (implicit in boundary check) |
| REQ-RULES-CTCUTOFF-005 | §5.3 | WfinalclsRule.php:46-49 |
| REQ-RULES-INDETCTS-001 | §5.5 | IndeterminateCtRule.php:40-44 |
| REQ-RULES-THRESH-001 | §6 | ThresholdRule.php:48-52 |
| REQ-RULES-THRESH-002 | §6 | (error persistence logic) |
| REQ-RULES-THRESH-003 | §6 | ThresholdRule.php:42-46 |
| REQ-RULES-DELTACT-001 | §5.4 | DeltaCtRule.php:47-65 |
| REQ-RULES-AMB-001 | §5.6 | AmbRule.php:40-42 |
| REQ-RULES-AMB-002 | §5.6 | (UI layer) |
| REQ-RULES-AMB-003 | §5.6.1 | (resolution processing) |
| REQ-RULES-AMB-004 | §5.6 | (system constraint) |
9. Design Decisions
| Decision | Rationale | Alternatives Considered |
|---|---|---|
| Separate Patient/Control rules | Different error codes, testability | Single rule with mode (rejected: complexity) |
| CLS discrepancy before CT discrepancy | Avoid duplicate flagging | Parallel execution (rejected: redundant errors) |
| Fixed CT discrepancy threshold (>2) | Industry standard | Configurable (rejected: consistency) |
| Shared discrepancy checkers | Code reuse with Combined Outcomes | Inline logic (rejected: duplication) |
| Permanent threshold errors | Audit trail integrity | Resolvable (rejected: data integrity) |
| NULL CT = Negative | Conservative interpretation | Skip (rejected: false positives) |
| NULL Quantity = Preserve | Asymmetric NULL handling | NULL = Negative (rejected: over-aggressive) |
10. Performance Considerations
| Scenario | Concern | Mitigation |
|---|---|---|
| Many observations per well | Iteration for each rule | Early exit on resolution codes |
| Delta CT combinations | Pair lookup for each target | Index on target_id, skip non-configured |
| Indeterminate CT check | All non-IC observation scan | Short-circuit on first negative |
| Discrepancy checkers | Called from multiple contexts | Stateless, no DB queries |
11. Related Documents
| Document | Relevant Sections |
|---|---|
| SRS: rule-wdcls.md | WDCLS requirements |
| SRS: rule-wdclsc.md | WDCLSC requirements |
| SRS: rule-wdct.md | WDCT requirements |
| SRS: rule-wdctc.md | WDCTC requirements |
| SRS: rule-ct-cutoff-wfinalcls.md | WFINALCLS requirements |
| SRS: rule-indeterminate-cts.md | INDETERMINATE_CTS requirements |
| SRS: rule-threshold.md | THRESHOLD requirements |
| SRS: rule-delta-ct.md | DELTA_CT requirements |
| SRS: rule-amb.md | AMB requirements |
| SDS: Rules Engine | Framework overview |
| SDS: Combined Outcomes | Discrepancy flag consumption |