Every 256th Setup — Python Bug Hunt

Modelled on the Therac-25 radiation therapy accidents (1985–1987), analysed by Nancy Leveson and Clark Turner.

  • Language: Python
  • Layer: Backend
  • Difficulty: Medium
  • Concepts: Overflow, State
  • Modelled on: Therac-25 · 1985–87
  • Visible tests: the first pass holds when out of position; pass 256 still checks the position
  • Reward: 50 XP for a complete fix

Briefing

Modelled on the Therac-25 radiation therapy accidents (1985–1987), analysed by Nancy Leveson and Clark Turner. In one of the software faults they documented, a one-byte flag was incremented on every pass of the set-up routine instead of being set to a fixed non-zero value. On every 256th pass it rolled over to zero — and zero meant "skip the check" that the turntable was in the right position. If the operator pressed the set button at that moment, treatment could proceed with the turntable out of place.

setup.py reconstructs that routine; hardware.py models the one-byte register.

Fix setup_pass so the position check runs on every single pass.

Bug report

BUG-CLASS3 · Priority: Critical (patient safety) · Reported by: physics QA

setup_pass(state, collimator_in_position) runs one pass of the set-up test:

  • state["passes"] increases by 1
  • state["class3"] is a one-byte flag (0..255) meaning "a position check is pending"; after every pass it must be non-zero
  • returns "HOLD" whenever the collimator is NOT in position and "READY" when it is — on every pass, however many passes have already run

Observed: during a long set-up, pass 256 reported READY with the collimator out of position.

Logs

[setup] pass 255 class3=255 chkcol=HOLD
[setup] pass 256 class3=0 chkcol=skipped -> READY
[setup] operator SET accepted

The code as shipped

src/therac/setup.py (editable)

hardware = bug_require("./hardware.py")


def setup_pass(state, collimator_in_position):
    state["passes"] += 1
    state["class3"] = (state["class3"] + 1) & hardware.BYTE_MASK
    if state["class3"] != 0:
        if not collimator_in_position:
            return "HOLD"
    return "READY"

Read-only context: src/therac/hardware.py.

Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More Python bug hunts.