STD: Downward Sigmoid Rule (DSIGMOID)
Version: v1.0.0
Status: Draft
SRS Source: docusaurus/docs/srs/rules/rule-downward-sigmoid.md
Rule Name: SIGMOID
Domain: RULES-DSIGMOID
Overview
This document specifies tests for the Downward Sigmoid rule using decision tables and test vectors. The rule validates amplification curve shapes against observation classifications to detect discrepancies that may indicate classification errors or instrument issues.
Rule Characteristics:
- Pure business logic (no UI)
- Sigmoid direction calculation based on middle vs penultimate reading values
- Classification-dependent validation (positive expects upward, negative expects downward)
- Multiple exclusion conditions (resolution, manual classification, ambiguous)
- Flag setting on validation failure
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-DSIGMOID-001 | Positive Observation Sigmoid Validation | 6 | 8 | 100% | None |
| REQ-RULES-DSIGMOID-002 | Negative Observation Sigmoid Validation | 6 | 8 | 100% | None |
| REQ-RULES-DSIGMOID-003 | Ambiguous Observation Exclusion | 2 | 4 | 100% | None |
| REQ-RULES-DSIGMOID-004 | Resolution and Manual Override Exclusion | 4 | 6 | 100% | None |
| REQ-RULES-DSIGMOID-005 | Classification Discrepancy Flag | 2 | 3 | 100% | None |
Totals: 5 REQs, 20 Conditions, 29 Test Vectors, 100% Coverage
| Variable | Type | Valid Values | Description |
|---|
obs.final_cls | string | Pos, Neg, Amb, null | Final observation classification |
obs.manual_cls | string? | null, Pos, Neg, Amb | Manual classification override |
obs.readings | array | numeric[] | Array of reading values |
well.resolution_code | string? | null, SIGMOID, ... | Well-level resolution code |
Derived Variables (Calculated)
| Variable | Formula | Description |
|---|
reading_count | length(obs.readings) | Number of readings in array |
middle_index | floor(reading_count / 2) | Index of middle reading |
penultimate_index | reading_count - 2 | Index of second-to-last reading |
middle_value | obs.readings[middle_index] | Value at middle position |
penultimate_value | obs.readings[penultimate_index] | Value at penultimate position |
sigmoid_direction | see logic below | Upward, Downward, or Not-a-Sigmoid |
Sigmoid Direction Logic
| Condition | Result |
|---|
| reading_count < 4 | Not-a-Sigmoid |
| middle_value > penultimate_value | Downward |
| middle_value < penultimate_value | Upward |
| middle_value = penultimate_value | Not-a-Sigmoid |
Output Variables
| Variable | Type | Description |
|---|
well.error_code | string? | INCORRECT_SIGMOID or null |
obs.classification_discrepancy_flag | bool | Flag indicating classification problem |
REQ-RULES-DSIGMOID-001: Positive Observation Sigmoid Validation
Decision Table: Positive Classification Validation
| TV | final_cls | readings | middle_val | penult_val | sigmoid_dir | error_code | Covers |
|---|
| TV-001-001 | Pos | [1,2,3,4] | 2 | 3 | Upward | null | AC: Upward sigmoid valid for positive |
| TV-001-002 | Pos | [4,3,2,1] | 3 | 2 | Downward | INCORRECT_SIGMOID | AC: Downward sigmoid invalid for positive |
| TV-001-003 | Pos | [1,2,3,4,5] | 3 | 4 | Upward | null | AC: 5 readings, upward valid |
| TV-001-004 | Pos | [5,4,3,2,1] | 3 | 2 | Downward | INCORRECT_SIGMOID | AC: 5 readings, downward invalid |
| TV-001-005 | Pos | [1,2,3,4,5,6] | 3 | 5 | Upward | null | AC: 6 readings, upward valid |
| TV-001-006 | Pos | [6,5,4,3,2,1] | 4 | 2 | Downward | INCORRECT_SIGMOID | AC: 6 readings, downward invalid |
Decision Table: Insufficient Readings (Positive)
| TV | final_cls | readings | reading_count | sigmoid_dir | error_code | Covers |
|---|
| TV-001-007 | Pos | [1] | 1 | Not-a-Sigmoid | null | AC: Minimum data requirement |
| TV-001-008 | Pos | [1,2,3] | 3 | Not-a-Sigmoid | null | AC: Minimum data requirement |
REQ-RULES-DSIGMOID-002: Negative Observation Sigmoid Validation
Decision Table: Negative Classification Validation
| TV | final_cls | readings | middle_val | penult_val | sigmoid_dir | error_code | Covers |
|---|
| TV-002-001 | Neg | [4,3,2,1] | 3 | 2 | Downward | null | AC: Downward sigmoid valid for negative |
| TV-002-002 | Neg | [1,2,3,4] | 2 | 3 | Upward | INCORRECT_SIGMOID | AC: Upward sigmoid invalid for negative |
| TV-002-003 | Neg | [5,4,3,2,1] | 3 | 2 | Downward | null | AC: 5 readings, downward valid |
| TV-002-004 | Neg | [1,2,3,4,5] | 3 | 4 | Upward | INCORRECT_SIGMOID | AC: 5 readings, upward invalid |
| TV-002-005 | Neg | [6,5,4,3,2,1] | 4 | 2 | Downward | null | AC: 6 readings, downward valid |
| TV-002-006 | Neg | [1,2,3,4,5,6] | 3 | 5 | Upward | INCORRECT_SIGMOID | AC: 6 readings, upward invalid |
Decision Table: Insufficient Readings (Negative)
| TV | final_cls | readings | reading_count | sigmoid_dir | error_code | Covers |
|---|
| TV-002-007 | Neg | [1,2] | 2 | Not-a-Sigmoid | null | AC: Minimum data requirement |
| TV-002-008 | Neg | [3,2,1] | 3 | Not-a-Sigmoid | null | AC: Minimum data requirement |
REQ-RULES-DSIGMOID-003: Ambiguous Observation Exclusion
Decision Table: Classification Exclusion
| TV | final_cls | readings | sigmoid_dir | rule_applied | error_code | Covers |
|---|
| TV-003-001 | null | [4,3,2,1] | Downward | false | null | AC: Null classification excluded |
| TV-003-002 | Amb | [4,3,2,1] | Downward | false | null | AC: Ambiguous classification excluded |
| TV-003-003 | null | [1,2,3,4] | Upward | false | null | AC: Null with upward excluded |
| TV-003-004 | Amb | [1,2,3,4] | Upward | false | null | AC: Ambiguous with upward excluded |
REQ-RULES-DSIGMOID-004: Resolution and Manual Override Exclusion
Decision Table: Resolution Code Exclusion
| TV | final_cls | resolution_code | readings | sigmoid_dir | rule_applied | error_code | Covers |
|---|
| TV-004-001 | Pos | SIGMOID | [4,3,2,1] | Downward | false | null | AC: SIGMOID resolution excludes rule |
| TV-004-002 | Neg | SIGMOID | [1,2,3,4] | Upward | false | null | AC: SIGMOID resolution excludes rule |
| TV-004-003 | Pos | null | [4,3,2,1] | Downward | true | INCORRECT_SIGMOID | AC: No resolution, rule applies |
Decision Table: Manual Classification Exclusion
| TV | final_cls | manual_cls | readings | sigmoid_dir | rule_applied | error_code | Covers |
|---|
| TV-004-004 | Pos | Pos | [4,3,2,1] | Downward | false | null | AC: Manual classification excludes rule |
| TV-004-005 | Neg | Neg | [1,2,3,4] | Upward | false | null | AC: Manual classification excludes rule |
| TV-004-006 | Pos | null | [4,3,2,1] | Downward | true | INCORRECT_SIGMOID | AC: No manual, rule applies |
REQ-RULES-DSIGMOID-005: Classification Discrepancy Flag
Decision Table: Flag Setting
| TV | final_cls | sigmoid_dir | error_code | discrepancy_flag | Covers |
|---|
| TV-005-001 | Pos | Downward | INCORRECT_SIGMOID | true | AC: Flag set on positive with downward |
| TV-005-002 | Neg | Upward | INCORRECT_SIGMOID | true | AC: Flag set on negative with upward |
| TV-005-003 | Pos | Upward | null | false | AC: No flag when validation passes |
Boundary Value Tests
Decision Table: Equal Middle and Penultimate Values
| TV | final_cls | readings | middle_val | penult_val | sigmoid_dir | error_code | Covers |
|---|
| TV-BND-001 | Pos | [1,2,2,4] | 2 | 2 | Not-a-Sigmoid | null | AC: Equal values = not sigmoid |
| TV-BND-002 | Neg | [4,2,2,1] | 2 | 2 | Not-a-Sigmoid | null | AC: Equal values = not sigmoid |
Decision Table: Minimum Valid Reading Count
| TV | final_cls | readings | reading_count | middle_idx | penult_idx | Covers |
|---|
| TV-BND-003 | Pos | [1,2,3,4] | 4 | 2 | 2 | AC: Exactly 4 readings (minimum) |
| TV-BND-004 | Pos | [1,2,3] | 3 | - | - | AC: 3 readings (below minimum) |
Exceptional Cases (From SRS Reference Data)
Decision Table: Exceptional Sigmoid Patterns
| TV | final_cls | readings | middle_idx | penult_idx | middle_val | penult_val | sigmoid_dir | error_code | Note |
|---|
| TV-EXC-001 | Pos | [6,5,4,4,5,6] | 3 | 4 | 4 | 5 | Upward | null | U-shaped curve |
| TV-EXC-002 | Pos | [5,4,3,4,5] | 2 | 3 | 3 | 4 | Upward | null | V-shaped curve |
| TV-EXC-003 | Neg | [1,2,3,3,2,1] | 3 | 4 | 3 | 2 | Downward | null | Inverted U-shaped |
| TV-EXC-004 | Neg | [1,2,3,2,1] | 2 | 3 | 3 | 2 | Downward | null | Inverted V-shaped |
Combined Exclusion Tests
Decision Table: Multiple Exclusion Conditions
| TV | final_cls | manual_cls | resolution_code | readings | rule_applied | error_code | Covers |
|---|
| TV-CMB-001 | Pos | Pos | SIGMOID | [4,3,2,1] | false | null | AC: Both exclusions present |
| TV-CMB-002 | Amb | null | SIGMOID | [4,3,2,1] | false | null | AC: Classification + resolution exclusion |
| TV-CMB-003 | null | Pos | null | [4,3,2,1] | false | null | AC: Classification + manual exclusion |
Test File Locations
| Requirement | Test File | Method |
|---|
| REQ-RULES-DSIGMOID-001 | tests/Unit/Rules/SigmoidRuleTest.php | TM-API |
| REQ-RULES-DSIGMOID-002 | tests/Unit/Rules/NegativeSigmoidRuleTest.php | TM-API |
| REQ-RULES-DSIGMOID-003 | tests/Unit/Rules/SigmoidRuleTest.php | TM-API |
| REQ-RULES-DSIGMOID-004 | tests/Unit/Rules/SigmoidRuleTest.php | TM-API |
| REQ-RULES-DSIGMOID-005 | tests/Unit/Rules/SigmoidRuleTest.php | TM-API |
Traceability to Existing Tests
| Requirement | Jira Tests | Automation Status |
|---|
| REQ-RULES-DSIGMOID-001 | BT-5165, BT-5254 | Automated |
| REQ-RULES-DSIGMOID-002 | BT-5165, BT-5254 | Automated |
| REQ-RULES-DSIGMOID-003 | BT-5165 | Automated |
| REQ-RULES-DSIGMOID-004 | BT-5221, BT-5220 | Automated |
| REQ-RULES-DSIGMOID-005 | BT-5221, BT-5228, BT-5254 | Automated |
Gap Analysis
Identified Gaps
| Gap | Requirement | Description | Priority | Owner |
|---|
| - | - | No gaps identified | - | - |
All requirements have corresponding Jira test tickets and automated test coverage.