NEMESynth-EMSO Get more information Account
Standards

Decision sheets: the rules travel with the data

Spectrum data moves between systems, but the rules for using it stay buried in each system's code, and when two nodes make different calls nobody can say why. Decision sheets put the rules in the record, in a form a spectrum manager can read.

What a decision sheet looks like

A decision sheet is a table. The left columns are the conditions, the right columns are the answers, and each row is one rule. If more than one row matches, the sheet's policy says which one wins. The cells use a small standard notation, explained below the example. In NEMESynth-EMSO the PACE triggers, alternate-frequency choices, priority rules, compliance checks and import rules are all sheets.

Here's the sheet that decides when a net moves down its PACE plan in the Halcyon exercise. It runs whenever something changes for a net: the power drops, a fiber is cut, a link budget stops closing, someone starts jamming the band.

#steppathmargin shortjammedprimary ok→ next→ reason
1not("primary")***"yes""primary""primary restored"
2"primary""down"***"alternate""primary down"
3"primary"*"yes"**"alternate""primary margin short"
4"primary"**"yes"*"alternate""primary jammed"
5"alternate""down"***"contingency""alternate down"
8"contingency""down"***"emergency""contingency down"
10*****?step"hold"

Part of the comm plan PACE sheet. The first matching row wins; rows 6, 7 and 9 are left out here. A second table on the same sheet decides who gets told. Going to emergency always notifies the spectrum manager and net control, and any move on a safety-of-life or medical net notifies the spectrum manager.

Reading the cells: S-FEEL

Each cell holds a short test or value written in S-FEEL (Simple Friendly Enough Expression Language), the cell language of the OMG Decision Model and Notation (DMN) standard. It has only values, comparisons, ranges, lists and "not", so you can read a sheet, check it and change it yourself. Because it's a published standard, a rule means the same thing in any tool that supports DMN.

In the cellIt means
"down"the value is exactly down
< 10less than 10, for example less than 10 dB of margin
[0..2)from 0 up to, but not including, 2
"primary", "alternate"either one
not("primary")anything except primary
*any value; this condition doesn't matter for the row
?stepan answer that keeps the current value, so the net stays where it is

So row 3 reads: if the net is on its primary and the link margin is short, go to the alternate and log "primary margin short". Row 10 catches everything else and holds.

Why put the sheets in SFAFx

Draft §3.7 of the SFAFx standard makes a sheet an SFAFx record, with its inputs and outputs, tables, S-FEEL cells, worked examples, validity checks and the order its tables run in. A set then carries its rules and its data under one hash.

Every node makes the same call

Nodes holding the same set run the same version of the sheet, so a net switches the same way everywhere, with no rule server to reach.

Decisions keep working when you're cut off

The rules run on the node. A node that's lost contact with everyone still decides, and decides the way its peers would.

You can always ask why

Every PACE switch records the sheet version and the row that fired, right next to the command it produced.

The rules are sealed too

The set's hash covers the rules as well as the data, so the other end knows nobody changed them on the way.

Host nations bring their own rules

A host nation's allocation table, protection criteria and priorities come in as sheets with its records and run the same at every node.

Open to anyone

Rules are exchanged as plain S-FEEL text in an open format, so any vendor can write a reader. Compiled forms are explicitly outside the standard.

Safe to run

A sheet can't do anything except produce its outputs. A sheet that fails its checks never runs, and its worked examples double as its tests.

More than triggers

The same format already parses SFAF on import. Generating records and learning rows from examples come next.

GRIPS, the engine underneath

GRIPS (Goose Rule-based Integrated Production System) is our port of the CLIPS 7.0 rule engine to the Goose language, built for this kind of work. Since 29 October 2026 NEMESynth-EMSO runs its decision sheets on GRIPS directly, and keeps CLIPS for the web build.

What it means for youThe evidenceStatus
Same answers as CLIPSMatches the CLIPS reference on every in-scope test, example and benchmark, checked by a differential fuzzer and a sweep of the builtins. All 112 of the reference's test files run section by section without a failure.Built
Faster on spectrum workBeats the C reference on every NEMESynth-EMSO job we've timed: spectrum deconfliction 0.67 s against 12.8 s, radio nets 5.36 s against 8.23 s, and the decision sheets 1.3 to 2.1 times faster.Built
A record of what ranEvery rule has an identity and a version you can roll back, and a watchdog stops a runaway rule set between firings.Built
Built around dataFacts are stored in tables and columns, and a map of which rules depend on which facts skips work a run can't need.Built
Reads sheets itselfA new parser reads S-FEEL, compiles sheets directly and runs their tables in dependency order, as §3.7 lays out.In progress
Rules decide what to listen toA rule's conditions and a topic's subscription name the same facts. Load a rule that needs a topic and the topic is subscribed; remove the last one and it's dropped.Planned

Rules over the live picture

GRIPS and the application share one in-memory database. Once a change is final it gets published. Incoming readings become facts. A command from another system becomes a fact inside a transaction: it's answered if the transaction commits, and refused with a reason if it rolls back. Spotting energy where nothing's authorized is just an ordinary rule:

(defrule unauthorized-energy
  (observation (freq-hz ?f) (power-dbm ?p&:(> ?p -90)) (site ?s) (at ?t))
  (not (assignment (lo-hz ?lo&:(<= ?lo ?f)) (hi-hz ?hi&:(>= ?hi ?f))
                   (area ?a&:(within ?s ?a)) (in-force-at ?t)))
  =>
  (assert (anomaly (freq-hz ?f) (site ?s) (at ?t))))

An example. It's part of the sensor-reading work that is Planned.

Goals over the rules

Goal graph for the Halcyon relief operation: Sense, Understand, Decide, Coordinate, Connect and Host nation goals, with commands and sheets as methods
The goals for Halcyon. Sense, Understand, Decide, Coordinate, Connect and Host nation sit under "Relief connected", with the commands and sheets that achieve each one. Each step is marked as asking first or acting while you watch, and the plan line lists the steps in order.

Sheets are steps toward a goal, alongside commands and the optimizer. Each goal says what counts as done and what each step costs. The scheduler picks the steps that get there, and you approve the plan.

Bring us one of your rules

Send us a PACE trigger, a priority rule or a host-nation constraint, and we'll show you it as a decision sheet running in the Halcyon exercise.

Get more information