quorum logoquorum

How it works

Write the rules. Check every situation. Run it on a chip.

quorum is a reasoning engine and toolchain for the decisions small machines make on their own: stop the pump or let it run, stop the transfer, call a person.

Rulebooks

Rules in plain words

A rulebook (a .cb file) lists what the instruments report, the conclusions those readings support, and the actions to take. It also lists what can knock a conclusion down:

  • Excuses: a benign explanation, such as "the pump changed duty point", that defeats a fault diagnosis
  • Doubts: a reason to distrust an instrument, such as "calibration past due"
  • Severity: a more dangerous conclusion wins over a milder one
  • Voting: "2 out of 3 level switches", written exactly like that
  • Time: "pressure high within 10 s after a start", "tripped 3 times in an hour" (more)

Every rule carries the document it came from, so an auditor can follow each one back to the page.

The rulebook language
a 2-out-of-3 tripexample
observe lt_a_high "transmitter A above setpoint"
observe lt_b_high "transmitter B above setpoint"
observe lt_c_high "transmitter C above setpoint"

claim level_high "two of three above setpoint"
  vote 2 of lt_a_high lt_b_high lt_c_high

action hold idle
action trip safe when level_high

The full check

Every situation, before the machine sees it

The compiler, cbc, solves every combination of readings. Not a sample: with 14 readings that is all 16,384 situations, and with 30 it is about a billion, which takes about two minutes on an 8-core PC.

A rulebook is refused, with the exact situation that breaks it, if any situation gives:

  • two actions at once, or no action at all
  • an answer that is not reached in time
  • an action that can never be chosen
  • a conclusion that nothing could ever argue against
OutcomeWhat the plant should do
DecidedExactly one action: do it
IndeterminateThe evidence is genuinely ambiguous: call a person
UnsatisfiedThe rulebook rejects every action: fix the rulebook
ConflictedTwo actions at once: a rulebook defect
FaultedThe computation did not finish: fall back to the hardwired interlock

Time

Rules that know what happened, and when

Many safety rules are about order and timing. Pressure that rises right after a start means a closed valve; the same pressure an hour later means a blockage. A relay that trips three times in an hour means the motor must not be restarted. A rulebook says this in plain words:

  • After: "pressure high within 10 s after the motor started"
  • Recently: "the bearing was hot at any time in the last 5 minutes"
  • How often: "the overload relay tripped 3 times in an hour"
  • Built on each other: "the bearing ran hot twice in an hour"
  • For how long: "hot for 5 seconds" before a threshold counts

Each timed reading is one more yes-or-no reading, so the full check still covers every combination. The board works out when to set it, and the bench test plays a script through time on the board's test clock, so an hour-long window is checked in seconds.

The guide to timed readings
a pump, with timeexample
reading dead_head "pressure high right after a start"
  when pressure_high within 10s after motor_started
reading repeated_trips "tripped 3 times in an hour"
  when overload_trip 3 times in 1h

claim closed_valve "pumping against a closed valve"
  needs dead_head
claim lockout "do not restart"
  needs repeated_trips

action stop safe when any closed_valve lockout

On the chip

Small, bounded, and the same every time

A rulebook that passes becomes a small image file. One firmware, loaded once, runs any image, and re-checks the image's fingerprint at start-up; a damaged, re-ordered or tampered image is refused on the board.

  • About 2.1 KB of flash and 2.7 KB of RAM for the engine with two real rulebooks
  • No heap, no recursion, no floating point
  • A proven bound on the number of steps; the Pico 2 took exactly the 140 steps the compiler predicted
  • The worst full cycle measured: 145 µs on a Pico 2, 284 µs on an Uno R4, against a 1 ms budget
BoardCoreStatus
Raspberry Pi Pico 2Cortex-M33Supported, measured
Arduino Uno R4 MinimaCortex-M4Supported, measured
Pico 1, Nano 33 BLE, Due, Giga R1M0+, M4, M3, M7Compiles, not measured
Raspberry Pi 4 / 5AArch64 LinuxEvery test suite runs
Arduino Uno / NanoAVR 8-bitNot supported

Explanations

Every answer comes with its reasons

Every conclusion is a path through declared rules, so "why did you stop the pump?" has a finite, printable answer. It names the readings it relied on, and the readings it only assumed were absent.

That second list is the one that matters when a sensor is dead. A dead sensor and a quiet one look the same, and quorum says which answers depended on the silence.

pump_witnessreal output, trimmed
dx_bearing_wear holds -- everything that disputes it is defeated:
  obs_bearing_temp_high holds
    def_calib_stale defeated
      obs_calib_overdue defeated -- ASSUMED ABSENT: no sensor asserted it.
      This is absence of evidence, not evidence of absence;
      a dead sensor reads the same way.

  14 steps, depth 5, of which 2 rest on ASSUMED ABSENCE of a reading

Starting points

From the paperwork the plant already has

Few plants want to write rules from a blank page. quorum starts from what exists:

  • HAZOP, LOPA and FMEA worksheets, imported into a draft rulebook. The importer reports deviations with no protection, and safeguards that name the same instrument as the cause.
  • Past records: a first rulebook learned from labelled history, for an engineer to review
  • An equipment manual, drafted by an AI model, quoting the manual word for word

Every draft is marked as a draft, with TODOs where the paperwork is silent, and the full check still applies.

quorum studio importing a worksheet