differential

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2026 License: AGPL-3.0 Imports: 1 Imported by: 0

README

Differential oracle

The conformance suite's four other oracles — golden traces, replay equivalence, structural invariants, metamorphic equivalence — all trust Atlas alone: they prove Atlas is self-consistent, not that it is right. This one runs the same process on an independent BPMN engine and asserts the outcomes agree, which is the only check that can catch a bug where Atlas is confidently, consistently wrong.

What it compares

The reference engine is bpmn-engine, a mature, independent JavaScript BPMN 2.0 executor. For each scenario the suite runs Atlas and the reference and compares a normalized projection:

  • did the instance complete, and
  • the set of activities that ran (deduplicated, sorted).

Variables are deliberately excluded — engines format values differently (Atlas FEEL vs. the reference's JavaScript), so the reliable cross-engine signal is the control-flow set, not the data. The activity set is what proves the interesting semantics: which gateway branch was taken, that a parallel join synchronized, that an inclusive split opened exactly the right branches and suppressed the default.

Why only a subset

BPMN portability stops at the executable extensions. Atlas speaks the zeebe: dialect and FEEL; no other engine does. So each reference model under reference/models/ is a hand-translation that keeps the same element ids and control flow but expresses scripts and conditions in the reference's dialect (JavaScript). Only pure control-flow scenarios are translated so far:

Scenario Semantics cross-checked
sequence plain token flow
exclusive-gateway data-based XOR + default flow
parallel-independent AND fork and synchronizing join
inclusive-gateway OR multi-choice split + synchronizing merge

Translating the parking, boundary, and structural scenarios (jobs, timers, messages, subprocess, …) is the way to grow this list — each needs a faithful reference encoding and a driver the reference can replay.

The control-flow independence holds even though the inline scripts are ours: the reference evaluates our value-computing scripts in a vm sandbox, but its own engine decides every routing, fork, and join — that is the independence the oracle rests on.

Running it

The live comparison is behind the differential build tag, so the default go test ./... and the repo-wide coverage gate never need Node.

cd conformance/differential/reference && npm ci && cd -
go test -tags differential ./conformance/differential/

Without the tag, go test ./conformance/differential/ runs only the pure projection unit tests (no Node required) — those are what the coverage gate sees.

Adding a reference scenario

  1. Hand-translate the Atlas model under reference/models/, keeping every element id identical and expressing scripts/conditions as JavaScript (environment.variables.x = …; next();, conditions next(null, <bool>);).
  2. Add the Atlas-scenario-name → reference-file entry to subset in differential_test.go.
  3. go test -tags differential ./conformance/differential/ and confirm agreement. A mismatch is either a translation bug or a real divergence worth investigating.

Documentation

Overview

Package differential is the conformance suite's cross-engine oracle: it runs the same process on Atlas and on an independent reference BPMN engine and compares a normalized outcome, so a control-flow bug shows up as disagreement with a second implementation — the one oracle the suite's other checks (golden, replay, invariants, metamorphic) can't provide, since they all trust Atlas alone.

The reference engine is Node's bpmn-engine (github.com/paed01/bpmn-engine), a mature, independent BPMN 2.0 executor, driven by the runner under reference/. Because Atlas's executable dialect (zeebe: extensions, FEEL) is not portable, the reference models under reference/models/ are hand-translations that keep the same element ids and control flow but express scripts and conditions in the reference dialect (JavaScript). The set of translated scenarios is a control-flow subset; see README.md.

The live comparison lives in differential_test.go behind the `differential` build tag, so it stays out of the default `go test ./...` and the coverage gate — it needs Node and an `npm ci` in reference/. This file holds only the pure, tested projection logic.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Projection

type Projection struct {
	Completed  bool
	Activities []string
}

Projection is the engine-independent outcome compared across engines: whether the instance completed, and the set of activities that ran. Variables are excluded on purpose — engines format values differently (Atlas FEEL vs. the reference's JavaScript), so the reliable cross-engine signal is the control-flow set, not the data.

func Project

func Project(completed bool, activities []string) Projection

Project normalizes a raw (completed, activities) pair: the activity list is deduplicated and sorted, so token-visit multiplicity and order — which legitimately differ across engines (Atlas records a join once per arriving token; the reference may not) — never cause a false mismatch.

func (Projection) Equal

func (p Projection) Equal(o Projection) bool

Equal reports whether two projections agree — same completion status and the same set of activities.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL