FAILURE MAP
← Case archive

FA-92781 / HVAC thermostat control / Open access

Reversing valve drops out between calls · case 01

The valve clicks over at the end of every cooling call and must shift back (with an equalization delay) on the next call.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The idle branch de-energizes the valve.

VERIFIED REPAIR

Hold the valve position while idle.

Unsuccessful approach: Reporting the valve de-energized while remembering it internally misreports the terminal.

Case contract

Heat pump reversing valve output (O/B terminal) and compressor per sample; samples are the call (heat, cool or None). An O-type valve is energized for cooling, a B-type for heating. The valve is de-energized at power-up and holds its last position while idle. On a sample where the valve changes position the compressor waits (off) for pressure equalization. Return [compressor, valve_energized].

Why this case matters

Residential and light-commercial thermostats make these decisions sample by sample; each defect changes equipment calls in a way that shows up as short cycling, comfort complaints or equipment stress.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(valve_type, samples):
    valve = False
    out = []
    for call in samples:
        if call is None:
            valve = False
            out.append([False, valve])
            continue
        want = (call == 'cool') if valve_type == 'O' else (call == 'heat')
        changed = want != valve
        valve = want
        out.append([not changed, valve])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: O valve season change',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'cool']],
   [[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]],
  ['regression: B valve idle hold',
   ['B', ['heat', None, 'heat']],
   [[False, True], [False, True], [True, True]]],
  ['control: first call heat on O',
   ['O', ['heat', 'heat', None, 'cool']],
   [[True, False], [True, False], [False, False], [False, True]]],
  ['control: first call cool on B',
   ['B', ['cool', None, 'cool', 'heat']],
   [[True, False], [False, False], [True, False], [False, True]]],
  ['regression: scenario 1',
   ['B', ['cool', 'heat', 'heat', None, None, 'cool', 'cool', 'heat', 'heat', 'heat', 'heat']],
   [[True, False],
    [False, True],
    [True, True],
    [False, True],
    [False, True],
    [False, False],
    [True, False],
    [False, True],
    [True, True],
    [True, True],
    [True, True]]],
  ['regression: scenario 2',
   ['B',
    ['heat',
     'heat',
     'cool',
     'cool',
     'heat',
     None,
     'heat',
     'cool',
     'heat',
     'heat',
     'cool',
     None,
     'heat',
     'cool']],
   [[False, True],
    [True, True],
    [False, False],
    [True, False],
    [False, True],
    [False, True],
    [True, True],
    [False, False],
    [False, True],
    [True, True],
    [False, False],
    [False, False],
    [False, True],
    [False, False]]],
  ['control: scenario 3',
   ['O', ['cool', 'cool', 'cool', 'heat', None, None, 'heat', 'cool', 'heat', 'heat', None, 'heat', 'heat']],
   [[False, True],
    [True, True],
    [True, True],
    [False, False],
    [False, False],
    [False, False],
    [True, False],
    [False, True],
    [False, False],
    [True, False],
    [False, False],
    [True, False],
    [True, False]]],
  ['regression: scenario 4',
   ['B', [None, 'heat', 'cool', 'cool', 'cool', 'cool', 'heat', 'heat', None, 'cool']],
   [[False, False],
    [False, True],
    [False, False],
    [True, False],
    [True, False],
    [True, False],
    [False, True],
    [True, True],
    [False, True],
    [False, False]]]],
 [['regression: B valve idle hold',
   ['B', ['heat', None, 'heat']],
   [[False, True], [False, True], [True, True]]],
  ['regression: scenario 1',
   ['B', [None, None, 'heat', None, 'cool', 'cool', 'cool', 'heat', None, 'cool', None]],
   [[False, False],
    [False, False],
    [False, True],
    [False, True],
    [False, False],
    [True, False],
    [True, False],
    [False, True],
    [False, True],
    [False, False],
    [False, False]]],
  ['regression: O valve season change',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'cool']],
   [[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]],
  ['control: first call heat on O',
   ['O', ['heat', 'heat', None, 'cool']],
   [[True, False], [True, False], [False, False], [False, True]]],
  ['control: first call cool on B',
   ['B', ['cool', None, 'cool', 'heat']],
   [[True, False], [False, False], [True, False], [False, True]]],
  ['regression: scenario 2',
   ['B', ['heat', 'cool', 'heat', None, 'cool', 'heat', None, 'heat', None, 'cool', None]],
   [[False, True],
    [False, False],
    [False, True],
    [False, True],
    [False, False],
    [False, True],
    [False, True],
    [True, True],
    [False, True],
    [False, False],
    [False, False]]],
  ['regression: scenario 3',
   ['B', [None, 'heat', None, None, None, None, 'cool', 'heat', 'heat', None]],
   [[False, False],
    [False, True],
    [False, True],
    [False, True],
    [False, True],
    [False, True],
    [False, False],
    [False, True],
    [True, True],
    [False, True]]],
  ['regression: scenario 4',
   ['B', ['heat', 'cool', 'cool', 'heat', 'heat', None, 'heat']],
   [[False, True], [False, False], [True, False], [False, True], [True, True], [False, True], [True, True]]]],
 [['regression: scenario 1',
   ['B', ['cool', 'heat', 'heat', 'cool', 'cool', None, 'cool', 'heat', 'heat', None, None, 'heat']],
   [[True, False],
    [False, True],
    [True, True],
    [False, False],
    [True, False],
    [False, False],
    [True, False],
    [False, True],
    [True, True],
    [False, True],
    [False, True],
    [True, True]]],
  ['regression: scenario 3',
   ['B', ['cool', 'heat', None, None, None, 'heat', 'heat', 'cool']],
   [[True, False],
    [False, True],
    [False, True],
    [False, True],
    [False, True],
    [True, True],
    [True, True],
    [False, False]]],
  ['regression: O valve season change',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'cool']],
   [[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]],
  ['regression: B valve idle hold',
   ['B', ['heat', None, 'heat']],
   [[False, True], [False, True], [True, True]]],
  ['control: first call heat on O',
   ['O', ['heat', 'heat', None, 'cool']],
   [[True, False], [True, False], [False, False], [False, True]]],
  ['control: first call cool on B',
   ['B', ['cool', None, 'cool', 'heat']],
   [[True, False], [False, False], [True, False], [False, True]]],
  ['control: scenario 2',
   ['O', [None, 'cool', 'heat', 'cool', 'heat', 'heat']],
   [[False, False], [False, True], [False, False], [False, True], [False, False], [True, False]]],
  ['regression: scenario 4',
   ['O', ['heat', 'heat', 'heat', 'heat', 'heat', 'cool', None, 'cool', 'cool', None]],
   [[True, False],
    [True, False],
    [True, False],
    [True, False],
    [True, False],
    [False, True],
    [False, True],
    [True, True],
    [True, True],
    [False, True]]]],
 [['regression: scenario 2',
   ['B', ['cool', 'cool', 'heat', None, 'cool', 'cool', None, 'cool']],
   [[True, False],
    [True, False],
    [False, True],
    [False, True],
    [False, False],
    [True, False],
    [False, False],
    [True, False]]],
  ['regression: scenario 3',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'heat', 'cool', 'heat', None, 'heat', None, 'heat']],
   [[False, True],
    [True, True],
    [False, True],
    [False, False],
    [True, False],
    [True, False],
    [False, True],
    [False, False],
    [False, False],
    [True, False],
    [False, False],
    [True, False]]],
  ['regression: O valve season change',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'cool']],
   [[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]],
  ['regression: B valve idle hold',
   ['B', ['heat', None, 'heat']],
   [[False, True], [False, True], [True, True]]],
  ['control: first call heat on O',
   ['O', ['heat', 'heat', None, 'cool']],
   [[True, False], [True, False], [False, False], [False, True]]],
  ['control: first call cool on B',
   ['B', ['cool', None, 'cool', 'heat']],
   [[True, False], [False, False], [True, False], [False, True]]],
  ['regression: scenario 1',
   ['O', ['heat', 'cool', None, 'cool', None, None, 'cool']],
   [[True, False], [False, True], [False, True], [True, True], [False, True], [False, True], [True, True]]],
  ['regression: scenario 4',
   ['O', ['cool', None, None, 'heat', 'cool', None, 'heat', None, None, 'cool', 'cool']],
   [[False, True],
    [False, True],
    [False, True],
    [False, False],
    [False, True],
    [False, True],
    [False, False],
    [False, False],
    [False, False],
    [False, True],
    [True, True]]]],
 [['regression: scenario 5',
   ['O', [None, 'cool', None, None, 'heat', 'cool', 'heat', None, 'cool', 'heat']],
   [[False, False],
    [False, True],
    [False, True],
    [False, True],
    [False, False],
    [False, True],
    [False, False],
    [False, False],
    [False, True],
    [False, False]]],
  ['regression: scenario 8',
   ['B',
    [None,
     'heat',
     'heat',
     'cool',
     'heat',
     'heat',
     'heat',
     'cool',
     'cool',
     'cool',
     'heat',
     'heat',
     None,
     None]],
   [[False, False],
    [False, True],
    [True, True],
    [False, False],
    [False, True],
    [True, True],
    [True, True],
    [False, False],
    [True, False],
    [True, False],
    [False, True],
    [True, True],
    [False, True],
    [False, True]]],
  ['regression: O valve season change',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'cool']],
   [[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]],
  ['regression: B valve idle hold',
   ['B', ['heat', None, 'heat']],
   [[False, True], [False, True], [True, True]]],
  ['control: first call heat on O',
   ['O', ['heat', 'heat', None, 'cool']],
   [[True, False], [True, False], [False, False], [False, True]]],
  ['control: first call cool on B',
   ['B', ['cool', None, 'cool', 'heat']],
   [[True, False], [False, False], [True, False], [False, True]]],
  ['regression: scenario 1',
   ['O', ['heat', None, 'cool', None, 'heat', 'cool', 'heat', 'cool', None, None, None]],
   [[True, False],
    [False, False],
    [False, True],
    [False, True],
    [False, False],
    [False, True],
    [False, False],
    [False, True],
    [False, True],
    [False, True],
    [False, True]]],
  ['control: scenario 2',
   ['B', [None, None, None, None, 'cool', None, 'heat', 'cool', None]],
   [[False, False],
    [False, False],
    [False, False],
    [False, False],
    [True, False],
    [False, False],
    [False, True],
    [False, False],
    [False, False]]]]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
regression: O valve season change[[False, True], [True, True], [False, False], [True, False], [True, False], [False, True]][[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]Failed
regression: B valve idle hold[[False, True], [False, False], [False, True]][[False, True], [False, True], [True, True]]Failed
control: first call heat on O[[True, False], [True, False], [False, False], [False, True]][[True, False], [True, False], [False, False], [False, True]]Passed
control: first call cool on B[[True, False], [False, False], [True, False], [False, True]][[True, False], [False, False], [True, False], [False, True]]Passed
regression: scenario 1[[True, False], [False, True], [True, True], [False, False], [False, False], [True, False], [True, False], [False, True], [True, True], [True, True], [True, True]][[True, False], [False, True], [True, True], [False, True], [False, True], [False, False], [True, False], [False, True], [True, True], [True, True], [True, True]]Failed
regression: scenario 2[[False, True], [True, True], [False, False], [True, False], [False, True], [False, False], [False, True], [False, False], [False, True], [True, True], [False, False], [False, False], [False, True], [False, False]][[False, True], [True, True], [False, False], [True, False], [False, True], [False, True], [True, True], [False, False], [False, True], [True, True], [False, False], [False, False], [False, True], [False, False]]Failed
control: scenario 3[[False, True], [True, True], [True, True], [False, False], [False, False], [False, False], [True, False], [False, True], [False, False], [True, False], [False, False], [True, False], [True, False]][[False, True], [True, True], [True, True], [False, False], [False, False], [False, False], [True, False], [False, True], [False, False], [True, False], [False, False], [True, False], [True, False]]Passed
regression: scenario 4[[False, False], [False, True], [False, False], [True, False], [True, False], [True, False], [False, True], [True, True], [False, False], [True, False]][[False, False], [False, True], [False, False], [True, False], [True, False], [True, False], [False, True], [True, True], [False, True], [False, False]]Failed

SHA-256 / a51383a89e68d67b96135209a68d3083422ce8a4f222eba32a94cc28cb362047

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(valve_type, samples):
    valve = False
    out = []
    for call in samples:
        if call is None:
            out.append([False, False])
            continue
        want = (call == 'cool') if valve_type == 'O' else (call == 'heat')
        changed = want != valve
        valve = want
        out.append([not changed, valve])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: O valve season change',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'cool']],
   [[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]],
  ['regression: B valve idle hold',
   ['B', ['heat', None, 'heat']],
   [[False, True], [False, True], [True, True]]],
  ['control: first call heat on O',
   ['O', ['heat', 'heat', None, 'cool']],
   [[True, False], [True, False], [False, False], [False, True]]],
  ['control: first call cool on B',
   ['B', ['cool', None, 'cool', 'heat']],
   [[True, False], [False, False], [True, False], [False, True]]],
  ['regression: scenario 1',
   ['B', ['cool', 'heat', 'heat', None, None, 'cool', 'cool', 'heat', 'heat', 'heat', 'heat']],
   [[True, False],
    [False, True],
    [True, True],
    [False, True],
    [False, True],
    [False, False],
    [True, False],
    [False, True],
    [True, True],
    [True, True],
    [True, True]]],
  ['regression: scenario 2',
   ['B',
    ['heat',
     'heat',
     'cool',
     'cool',
     'heat',
     None,
     'heat',
     'cool',
     'heat',
     'heat',
     'cool',
     None,
     'heat',
     'cool']],
   [[False, True],
    [True, True],
    [False, False],
    [True, False],
    [False, True],
    [False, True],
    [True, True],
    [False, False],
    [False, True],
    [True, True],
    [False, False],
    [False, False],
    [False, True],
    [False, False]]],
  ['control: scenario 3',
   ['O', ['cool', 'cool', 'cool', 'heat', None, None, 'heat', 'cool', 'heat', 'heat', None, 'heat', 'heat']],
   [[False, True],
    [True, True],
    [True, True],
    [False, False],
    [False, False],
    [False, False],
    [True, False],
    [False, True],
    [False, False],
    [True, False],
    [False, False],
    [True, False],
    [True, False]]],
  ['regression: scenario 4',
   ['B', [None, 'heat', 'cool', 'cool', 'cool', 'cool', 'heat', 'heat', None, 'cool']],
   [[False, False],
    [False, True],
    [False, False],
    [True, False],
    [True, False],
    [True, False],
    [False, True],
    [True, True],
    [False, True],
    [False, False]]]],
 [['regression: B valve idle hold',
   ['B', ['heat', None, 'heat']],
   [[False, True], [False, True], [True, True]]],
  ['regression: scenario 1',
   ['B', [None, None, 'heat', None, 'cool', 'cool', 'cool', 'heat', None, 'cool', None]],
   [[False, False],
    [False, False],
    [False, True],
    [False, True],
    [False, False],
    [True, False],
    [True, False],
    [False, True],
    [False, True],
    [False, False],
    [False, False]]],
  ['regression: O valve season change',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'cool']],
   [[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]],
  ['control: first call heat on O',
   ['O', ['heat', 'heat', None, 'cool']],
   [[True, False], [True, False], [False, False], [False, True]]],
  ['control: first call cool on B',
   ['B', ['cool', None, 'cool', 'heat']],
   [[True, False], [False, False], [True, False], [False, True]]],
  ['regression: scenario 2',
   ['B', ['heat', 'cool', 'heat', None, 'cool', 'heat', None, 'heat', None, 'cool', None]],
   [[False, True],
    [False, False],
    [False, True],
    [False, True],
    [False, False],
    [False, True],
    [False, True],
    [True, True],
    [False, True],
    [False, False],
    [False, False]]],
  ['regression: scenario 3',
   ['B', [None, 'heat', None, None, None, None, 'cool', 'heat', 'heat', None]],
   [[False, False],
    [False, True],
    [False, True],
    [False, True],
    [False, True],
    [False, True],
    [False, False],
    [False, True],
    [True, True],
    [False, True]]],
  ['regression: scenario 4',
   ['B', ['heat', 'cool', 'cool', 'heat', 'heat', None, 'heat']],
   [[False, True], [False, False], [True, False], [False, True], [True, True], [False, True], [True, True]]]],
 [['regression: scenario 1',
   ['B', ['cool', 'heat', 'heat', 'cool', 'cool', None, 'cool', 'heat', 'heat', None, None, 'heat']],
   [[True, False],
    [False, True],
    [True, True],
    [False, False],
    [True, False],
    [False, False],
    [True, False],
    [False, True],
    [True, True],
    [False, True],
    [False, True],
    [True, True]]],
  ['regression: scenario 3',
   ['B', ['cool', 'heat', None, None, None, 'heat', 'heat', 'cool']],
   [[True, False],
    [False, True],
    [False, True],
    [False, True],
    [False, True],
    [True, True],
    [True, True],
    [False, False]]],
  ['regression: O valve season change',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'cool']],
   [[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]],
  ['regression: B valve idle hold',
   ['B', ['heat', None, 'heat']],
   [[False, True], [False, True], [True, True]]],
  ['control: first call heat on O',
   ['O', ['heat', 'heat', None, 'cool']],
   [[True, False], [True, False], [False, False], [False, True]]],
  ['control: first call cool on B',
   ['B', ['cool', None, 'cool', 'heat']],
   [[True, False], [False, False], [True, False], [False, True]]],
  ['control: scenario 2',
   ['O', [None, 'cool', 'heat', 'cool', 'heat', 'heat']],
   [[False, False], [False, True], [False, False], [False, True], [False, False], [True, False]]],
  ['regression: scenario 4',
   ['O', ['heat', 'heat', 'heat', 'heat', 'heat', 'cool', None, 'cool', 'cool', None]],
   [[True, False],
    [True, False],
    [True, False],
    [True, False],
    [True, False],
    [False, True],
    [False, True],
    [True, True],
    [True, True],
    [False, True]]]],
 [['regression: scenario 2',
   ['B', ['cool', 'cool', 'heat', None, 'cool', 'cool', None, 'cool']],
   [[True, False],
    [True, False],
    [False, True],
    [False, True],
    [False, False],
    [True, False],
    [False, False],
    [True, False]]],
  ['regression: scenario 3',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'heat', 'cool', 'heat', None, 'heat', None, 'heat']],
   [[False, True],
    [True, True],
    [False, True],
    [False, False],
    [True, False],
    [True, False],
    [False, True],
    [False, False],
    [False, False],
    [True, False],
    [False, False],
    [True, False]]],
  ['regression: O valve season change',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'cool']],
   [[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]],
  ['regression: B valve idle hold',
   ['B', ['heat', None, 'heat']],
   [[False, True], [False, True], [True, True]]],
  ['control: first call heat on O',
   ['O', ['heat', 'heat', None, 'cool']],
   [[True, False], [True, False], [False, False], [False, True]]],
  ['control: first call cool on B',
   ['B', ['cool', None, 'cool', 'heat']],
   [[True, False], [False, False], [True, False], [False, True]]],
  ['regression: scenario 1',
   ['O', ['heat', 'cool', None, 'cool', None, None, 'cool']],
   [[True, False], [False, True], [False, True], [True, True], [False, True], [False, True], [True, True]]],
  ['regression: scenario 4',
   ['O', ['cool', None, None, 'heat', 'cool', None, 'heat', None, None, 'cool', 'cool']],
   [[False, True],
    [False, True],
    [False, True],
    [False, False],
    [False, True],
    [False, True],
    [False, False],
    [False, False],
    [False, False],
    [False, True],
    [True, True]]]],
 [['regression: scenario 5',
   ['O', [None, 'cool', None, None, 'heat', 'cool', 'heat', None, 'cool', 'heat']],
   [[False, False],
    [False, True],
    [False, True],
    [False, True],
    [False, False],
    [False, True],
    [False, False],
    [False, False],
    [False, True],
    [False, False]]],
  ['regression: scenario 8',
   ['B',
    [None,
     'heat',
     'heat',
     'cool',
     'heat',
     'heat',
     'heat',
     'cool',
     'cool',
     'cool',
     'heat',
     'heat',
     None,
     None]],
   [[False, False],
    [False, True],
    [True, True],
    [False, False],
    [False, True],
    [True, True],
    [True, True],
    [False, False],
    [True, False],
    [True, False],
    [False, True],
    [True, True],
    [False, True],
    [False, True]]],
  ['regression: O valve season change',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'cool']],
   [[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]],
  ['regression: B valve idle hold',
   ['B', ['heat', None, 'heat']],
   [[False, True], [False, True], [True, True]]],
  ['control: first call heat on O',
   ['O', ['heat', 'heat', None, 'cool']],
   [[True, False], [True, False], [False, False], [False, True]]],
  ['control: first call cool on B',
   ['B', ['cool', None, 'cool', 'heat']],
   [[True, False], [False, False], [True, False], [False, True]]],
  ['regression: scenario 1',
   ['O', ['heat', None, 'cool', None, 'heat', 'cool', 'heat', 'cool', None, None, None]],
   [[True, False],
    [False, False],
    [False, True],
    [False, True],
    [False, False],
    [False, True],
    [False, False],
    [False, True],
    [False, True],
    [False, True],
    [False, True]]],
  ['control: scenario 2',
   ['B', [None, None, None, None, 'cool', None, 'heat', 'cool', None]],
   [[False, False],
    [False, False],
    [False, False],
    [False, False],
    [True, False],
    [False, False],
    [False, True],
    [False, False],
    [False, False]]]]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
regression: O valve season change[[False, True], [True, True], [False, False], [False, False], [True, False], [False, True]][[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]Failed
regression: B valve idle hold[[False, True], [False, False], [True, True]][[False, True], [False, True], [True, True]]Failed
control: first call heat on O[[True, False], [True, False], [False, False], [False, True]][[True, False], [True, False], [False, False], [False, True]]Passed
control: first call cool on B[[True, False], [False, False], [True, False], [False, True]][[True, False], [False, False], [True, False], [False, True]]Passed
regression: scenario 1[[True, False], [False, True], [True, True], [False, False], [False, False], [False, False], [True, False], [False, True], [True, True], [True, True], [True, True]][[True, False], [False, True], [True, True], [False, True], [False, True], [False, False], [True, False], [False, True], [True, True], [True, True], [True, True]]Failed
regression: scenario 2[[False, True], [True, True], [False, False], [True, False], [False, True], [False, False], [True, True], [False, False], [False, True], [True, True], [False, False], [False, False], [False, True], [False, False]][[False, True], [True, True], [False, False], [True, False], [False, True], [False, True], [True, True], [False, False], [False, True], [True, True], [False, False], [False, False], [False, True], [False, False]]Failed
control: scenario 3[[False, True], [True, True], [True, True], [False, False], [False, False], [False, False], [True, False], [False, True], [False, False], [True, False], [False, False], [True, False], [True, False]][[False, True], [True, True], [True, True], [False, False], [False, False], [False, False], [True, False], [False, True], [False, False], [True, False], [False, False], [True, False], [True, False]]Passed
regression: scenario 4[[False, False], [False, True], [False, False], [True, False], [True, False], [True, False], [False, True], [True, True], [False, False], [False, False]][[False, False], [False, True], [False, False], [True, False], [True, False], [True, False], [False, True], [True, True], [False, True], [False, False]]Failed

SHA-256 / 93fd2ee97f0b9eb59c64074f161947649fd2b1ac79f5571a08c90d064a4290f0

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(valve_type, samples):
    valve = False
    out = []
    for call in samples:
        if call is None:
            out.append([False, valve])
            continue
        want = (call == 'cool') if valve_type == 'O' else (call == 'heat')
        changed = want != valve
        valve = want
        out.append([not changed, valve])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: O valve season change',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'cool']],
   [[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]],
  ['regression: B valve idle hold',
   ['B', ['heat', None, 'heat']],
   [[False, True], [False, True], [True, True]]],
  ['control: first call heat on O',
   ['O', ['heat', 'heat', None, 'cool']],
   [[True, False], [True, False], [False, False], [False, True]]],
  ['control: first call cool on B',
   ['B', ['cool', None, 'cool', 'heat']],
   [[True, False], [False, False], [True, False], [False, True]]],
  ['regression: scenario 1',
   ['B', ['cool', 'heat', 'heat', None, None, 'cool', 'cool', 'heat', 'heat', 'heat', 'heat']],
   [[True, False],
    [False, True],
    [True, True],
    [False, True],
    [False, True],
    [False, False],
    [True, False],
    [False, True],
    [True, True],
    [True, True],
    [True, True]]],
  ['regression: scenario 2',
   ['B',
    ['heat',
     'heat',
     'cool',
     'cool',
     'heat',
     None,
     'heat',
     'cool',
     'heat',
     'heat',
     'cool',
     None,
     'heat',
     'cool']],
   [[False, True],
    [True, True],
    [False, False],
    [True, False],
    [False, True],
    [False, True],
    [True, True],
    [False, False],
    [False, True],
    [True, True],
    [False, False],
    [False, False],
    [False, True],
    [False, False]]],
  ['control: scenario 3',
   ['O', ['cool', 'cool', 'cool', 'heat', None, None, 'heat', 'cool', 'heat', 'heat', None, 'heat', 'heat']],
   [[False, True],
    [True, True],
    [True, True],
    [False, False],
    [False, False],
    [False, False],
    [True, False],
    [False, True],
    [False, False],
    [True, False],
    [False, False],
    [True, False],
    [True, False]]],
  ['regression: scenario 4',
   ['B', [None, 'heat', 'cool', 'cool', 'cool', 'cool', 'heat', 'heat', None, 'cool']],
   [[False, False],
    [False, True],
    [False, False],
    [True, False],
    [True, False],
    [True, False],
    [False, True],
    [True, True],
    [False, True],
    [False, False]]]],
 [['regression: B valve idle hold',
   ['B', ['heat', None, 'heat']],
   [[False, True], [False, True], [True, True]]],
  ['regression: scenario 1',
   ['B', [None, None, 'heat', None, 'cool', 'cool', 'cool', 'heat', None, 'cool', None]],
   [[False, False],
    [False, False],
    [False, True],
    [False, True],
    [False, False],
    [True, False],
    [True, False],
    [False, True],
    [False, True],
    [False, False],
    [False, False]]],
  ['regression: O valve season change',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'cool']],
   [[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]],
  ['control: first call heat on O',
   ['O', ['heat', 'heat', None, 'cool']],
   [[True, False], [True, False], [False, False], [False, True]]],
  ['control: first call cool on B',
   ['B', ['cool', None, 'cool', 'heat']],
   [[True, False], [False, False], [True, False], [False, True]]],
  ['regression: scenario 2',
   ['B', ['heat', 'cool', 'heat', None, 'cool', 'heat', None, 'heat', None, 'cool', None]],
   [[False, True],
    [False, False],
    [False, True],
    [False, True],
    [False, False],
    [False, True],
    [False, True],
    [True, True],
    [False, True],
    [False, False],
    [False, False]]],
  ['regression: scenario 3',
   ['B', [None, 'heat', None, None, None, None, 'cool', 'heat', 'heat', None]],
   [[False, False],
    [False, True],
    [False, True],
    [False, True],
    [False, True],
    [False, True],
    [False, False],
    [False, True],
    [True, True],
    [False, True]]],
  ['regression: scenario 4',
   ['B', ['heat', 'cool', 'cool', 'heat', 'heat', None, 'heat']],
   [[False, True], [False, False], [True, False], [False, True], [True, True], [False, True], [True, True]]]],
 [['regression: scenario 1',
   ['B', ['cool', 'heat', 'heat', 'cool', 'cool', None, 'cool', 'heat', 'heat', None, None, 'heat']],
   [[True, False],
    [False, True],
    [True, True],
    [False, False],
    [True, False],
    [False, False],
    [True, False],
    [False, True],
    [True, True],
    [False, True],
    [False, True],
    [True, True]]],
  ['regression: scenario 3',
   ['B', ['cool', 'heat', None, None, None, 'heat', 'heat', 'cool']],
   [[True, False],
    [False, True],
    [False, True],
    [False, True],
    [False, True],
    [True, True],
    [True, True],
    [False, False]]],
  ['regression: O valve season change',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'cool']],
   [[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]],
  ['regression: B valve idle hold',
   ['B', ['heat', None, 'heat']],
   [[False, True], [False, True], [True, True]]],
  ['control: first call heat on O',
   ['O', ['heat', 'heat', None, 'cool']],
   [[True, False], [True, False], [False, False], [False, True]]],
  ['control: first call cool on B',
   ['B', ['cool', None, 'cool', 'heat']],
   [[True, False], [False, False], [True, False], [False, True]]],
  ['control: scenario 2',
   ['O', [None, 'cool', 'heat', 'cool', 'heat', 'heat']],
   [[False, False], [False, True], [False, False], [False, True], [False, False], [True, False]]],
  ['regression: scenario 4',
   ['O', ['heat', 'heat', 'heat', 'heat', 'heat', 'cool', None, 'cool', 'cool', None]],
   [[True, False],
    [True, False],
    [True, False],
    [True, False],
    [True, False],
    [False, True],
    [False, True],
    [True, True],
    [True, True],
    [False, True]]]],
 [['regression: scenario 2',
   ['B', ['cool', 'cool', 'heat', None, 'cool', 'cool', None, 'cool']],
   [[True, False],
    [True, False],
    [False, True],
    [False, True],
    [False, False],
    [True, False],
    [False, False],
    [True, False]]],
  ['regression: scenario 3',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'heat', 'cool', 'heat', None, 'heat', None, 'heat']],
   [[False, True],
    [True, True],
    [False, True],
    [False, False],
    [True, False],
    [True, False],
    [False, True],
    [False, False],
    [False, False],
    [True, False],
    [False, False],
    [True, False]]],
  ['regression: O valve season change',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'cool']],
   [[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]],
  ['regression: B valve idle hold',
   ['B', ['heat', None, 'heat']],
   [[False, True], [False, True], [True, True]]],
  ['control: first call heat on O',
   ['O', ['heat', 'heat', None, 'cool']],
   [[True, False], [True, False], [False, False], [False, True]]],
  ['control: first call cool on B',
   ['B', ['cool', None, 'cool', 'heat']],
   [[True, False], [False, False], [True, False], [False, True]]],
  ['regression: scenario 1',
   ['O', ['heat', 'cool', None, 'cool', None, None, 'cool']],
   [[True, False], [False, True], [False, True], [True, True], [False, True], [False, True], [True, True]]],
  ['regression: scenario 4',
   ['O', ['cool', None, None, 'heat', 'cool', None, 'heat', None, None, 'cool', 'cool']],
   [[False, True],
    [False, True],
    [False, True],
    [False, False],
    [False, True],
    [False, True],
    [False, False],
    [False, False],
    [False, False],
    [False, True],
    [True, True]]]],
 [['regression: scenario 5',
   ['O', [None, 'cool', None, None, 'heat', 'cool', 'heat', None, 'cool', 'heat']],
   [[False, False],
    [False, True],
    [False, True],
    [False, True],
    [False, False],
    [False, True],
    [False, False],
    [False, False],
    [False, True],
    [False, False]]],
  ['regression: scenario 8',
   ['B',
    [None,
     'heat',
     'heat',
     'cool',
     'heat',
     'heat',
     'heat',
     'cool',
     'cool',
     'cool',
     'heat',
     'heat',
     None,
     None]],
   [[False, False],
    [False, True],
    [True, True],
    [False, False],
    [False, True],
    [True, True],
    [True, True],
    [False, False],
    [True, False],
    [True, False],
    [False, True],
    [True, True],
    [False, True],
    [False, True]]],
  ['regression: O valve season change',
   ['O', ['cool', 'cool', None, 'heat', 'heat', 'cool']],
   [[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]],
  ['regression: B valve idle hold',
   ['B', ['heat', None, 'heat']],
   [[False, True], [False, True], [True, True]]],
  ['control: first call heat on O',
   ['O', ['heat', 'heat', None, 'cool']],
   [[True, False], [True, False], [False, False], [False, True]]],
  ['control: first call cool on B',
   ['B', ['cool', None, 'cool', 'heat']],
   [[True, False], [False, False], [True, False], [False, True]]],
  ['regression: scenario 1',
   ['O', ['heat', None, 'cool', None, 'heat', 'cool', 'heat', 'cool', None, None, None]],
   [[True, False],
    [False, False],
    [False, True],
    [False, True],
    [False, False],
    [False, True],
    [False, False],
    [False, True],
    [False, True],
    [False, True],
    [False, True]]],
  ['control: scenario 2',
   ['B', [None, None, None, None, 'cool', None, 'heat', 'cool', None]],
   [[False, False],
    [False, False],
    [False, False],
    [False, False],
    [True, False],
    [False, False],
    [False, True],
    [False, False],
    [False, False]]]]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
regression: O valve season change[[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]][[False, True], [True, True], [False, True], [False, False], [True, False], [False, True]]Passed
regression: B valve idle hold[[False, True], [False, True], [True, True]][[False, True], [False, True], [True, True]]Passed
control: first call heat on O[[True, False], [True, False], [False, False], [False, True]][[True, False], [True, False], [False, False], [False, True]]Passed
control: first call cool on B[[True, False], [False, False], [True, False], [False, True]][[True, False], [False, False], [True, False], [False, True]]Passed
regression: scenario 1[[True, False], [False, True], [True, True], [False, True], [False, True], [False, False], [True, False], [False, True], [True, True], [True, True], [True, True]][[True, False], [False, True], [True, True], [False, True], [False, True], [False, False], [True, False], [False, True], [True, True], [True, True], [True, True]]Passed
regression: scenario 2[[False, True], [True, True], [False, False], [True, False], [False, True], [False, True], [True, True], [False, False], [False, True], [True, True], [False, False], [False, False], [False, True], [False, False]][[False, True], [True, True], [False, False], [True, False], [False, True], [False, True], [True, True], [False, False], [False, True], [True, True], [False, False], [False, False], [False, True], [False, False]]Passed
control: scenario 3[[False, True], [True, True], [True, True], [False, False], [False, False], [False, False], [True, False], [False, True], [False, False], [True, False], [False, False], [True, False], [True, False]][[False, True], [True, True], [True, True], [False, False], [False, False], [False, False], [True, False], [False, True], [False, False], [True, False], [False, False], [True, False], [True, False]]Passed
regression: scenario 4[[False, False], [False, True], [False, False], [True, False], [True, False], [True, False], [False, True], [True, True], [False, True], [False, False]][[False, False], [False, True], [False, False], [True, False], [True, False], [True, False], [False, True], [True, True], [False, True], [False, False]]Passed

SHA-256 / db0530edcb222da8ca5893ff150403abe4795114a33125e57ee7bb8ff32b3462

Verification & scope

A deterministic bounded teaching model of one thermostat or HVAC controller decision evaluated per sample. Temperatures are integer tenths of a degree Fahrenheit unless stated otherwise. The contract is a stipulated toy convention, not a claim of conformance to any manufacturer, ASHRAE guideline or code. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:51:49.092427+00:00.

Case digest / 91a9e15dee98b776add1c8b2edf9ca49ded69bcf8aa11182e8d50dbc221ec29e