flowRS Open the IDE

Form contract

Every program flowRS exports — an app for this computer, an app for a Linux board, a microcontroller's whole firmware — carries a FORM.json beside its source. It lists the properties below, 16 of them, and for each one says what enforces it, whether it holds for this program (live), holds in part (partial) or does not hold yet (not yet), why, and the evidence: the tests, proofs and tools in flowRS's gate that enforce it, and what was checked on this program when it was exported. A property that is not a property of that kind of program (no heap, on a computer) says so. The project's README.md states the same contract in plain words.

No status is written by hand. Each is computed when the program is exported, from the program as generated (its unsafe, read as syntax; its #![no_std]; its failure path), its graph (the nodes against what the generator lowers, the units on each wire), its Cargo.lock against flowRS's own, and, for a firmware, the board's binding, its twin, and the program's own Kani proof: a firmware ships its harness in proof/ with its record, proof/proofs.json, and the no-panic property is live only when that record says Kani proved exactly this program (the SHA-256 of its mod flow), every cover reached. Where flowRS's build host has proved the same program, the record arrives proved; otherwise flowrsc prove runs it, within a memory and a time budget. A test holds every live or partial claim to a second reading of the same files and fails when a status claims more than the code enforces.

The format is published as a JSON Schema: /schemas/form-contract-1.json ($schema in every FORM.json).

16
properties
16
example apps exported
10
firmware exported
14
board twins

The properties

The counts are this build's: each example on the editor's start screen exported as an app (16 exported), and the board generator's acceptance graph (every embedded widget but PWM) exported as a firmware for each board the generator covers, on both executors (10 exported). Each export's own contract is read back and counted.

#PropertyEnforced byExample appsFirmware
1Memory safety; no data race between an interrupt and the main loop
conformance: the generated program
rustc's borrow checker (with Send and Sync); the generated runtime never enables an interrupt16 live10 live
2No heap: no_std, every buffer sized from the graph
conformance: the generated program
the MCU generator (flowrs-core codegen::mcu), then rustc16 not applicable10 live
3A closed node set: nothing silently skipped
structure: the graph
the generators, which refuse by name any node they cannot lower16 live10 live
4Pins and buses allocated without collision
structure: the graph
codegen::mcu::bind, against the flowrs-boards model and the chip's signal tables16 not applicable10 live
5Exclusive peripheral ownership; no use before configuration
structure: the graph
the generated Board: the peripherals taken once, the init order as a chain of typestates (codegen::board)16 not applicable10 live
6A static schedule and bounded queues
conformance: the generated program
codegen: one pass of straight-line calls in the graph's order; the partitioner's compile-time link slots16 not applicable10 live
7Loops never faster than their edges allow
conformance: the generated program
the partitioner's 10x rule, against tails measured by tools/perfbench16 not applicable10 not applicable
8Units and clocks agree on every wire that carries a number
structure: the graph
the wire type check (flowrs-core graph::quantity), with units carried along the wires (graph::units); a mismatch is refused until a conversion node sits between8 live
3 partial
5 not applicable
10 not applicable
9Register configuration matches the chip
conformance: the generated program
flowrs-regdb's register check (rung 1) and processor-in-the-loop runs on the twin (flowrs-pil)16 not applicable10 partial
10The same behaviour in the browser and in the compiled program
conformance: the generated program
one implementation at both tiers; tier-differential tests; scipy and MNE oracles16 live10 partial
11Instruments always returned to a safe state
conformance: the generated program
codegen::handles::audit, which refuses any program that could skip an instrument handle's destructor2 live
14 not applicable
10 not applicable
12Defined behaviour when a HAL call fails on the microcontroller
conformance: the generated program
the generated runtime's failure path (codegen::board, flowrs_hal::rt)16 not applicable10 live
13The generated program cannot panic or overflow
conformance: the generated program
Kani16 not yet10 live
14No hardware action without a person's approval
conformance: the generated program
flowRS's approval envelope: approve-by-hash, server-held leases, signed policies, a hash-chained audit log6 partial
10 not applicable
10 partial
15The export builds the same way anywhere, under open licences
conformance: the generated program
the export's Cargo.lock, from flowRS's own; tools/appexport-verify.sh builds it --locked with no credentials; the licence audits16 live10 live
16Behaviour confirmed on the physical device
conformance: the generated program
a recorded run on a leased bench6 not yet
10 not applicable
10 not yet

Not counted, because the exporter refuses them, by name:

  • ds-sales: the program needs polars, which the Linux project generator has no pinned version for
  • ds-regression: the program needs polars, which the Linux project generator has no pinned version for
  • ml-classify: the program needs flowrs_ml, polars, tract_onnx, which the Linux project generator has no pinned version for
  • detect-blobs: the program needs image, imageproc, which the Linux project generator has no pinned version for

The software bill of materials

Every export that carries its Cargo.lock carries sbom.cdx.json beside it: CycloneDX 1.6 JSON made from that lock, so it lists every package the project can build, for any feature and target. Each crates.io crate is there with its package URL, its SHA-256 and the licence its own manifest declares, each flowRS crate in vendor/ with its licence, and the lock's dependency graph with them. FORM.json names it in its sbom member, with its SHA-256 and the lock's, and the exporter refuses to ship one its lock does not bear out. Of the exports counted above, 26 carry one, listing from 15 to 23 components.

What each board's twin models

A firmware's contract carries its board's fidelity contract, generated from the twin census: the rung of the twin ladder its twin stands on, what executes its CPU, and which of its part's peripherals a model answers. The register-configuration property names, for each peripheral the program uses, whether the twin models it.

BoardName and partTwinEnginePeripherals modelledNot modelled
blue_pillSTM32 Blue Pill
stm32f103c8
FullflowRS's pure-Rust Cortex-M core, in the page26 of 32BKP, CAN, CRC, IWDG, RTC, WWDG
esp32_c3_devkitmESP32-C3-DevKitM-1
esp32c3
Nonenothing executes itnot measured—
esp32_devkitcESP32-DevKitC
esp32
FullEspressif's QEMU, built to wasm64, in the page33 of 58BB, CPU_CTRL, DAC1, DAC2, ETH, FLASH, FROM_CPU_INTR2, FROM_CPU_INTR3, GPIO_SD, HINF, I2S0, I2S1, IPC, LP_I2C0, NRX, PCNT, PSRAM, RMT, RTC_TIMER, SDHOST, SLC, SLCHOST, TOUCH, UHCI0, UHCI1
esp32_s3_devkitcESP32-S3-DevKitC-1
esp32s3
PartialEspressif's QEMU, built to wasm64, in the page42 of 65ASSIST_DEBUG, CPU_CTRL, FLASH, FROM_CPU_INTR2, FROM_CPU_INTR3, GPIO_DEDICATED, GPIO_SD, I2S0, I2S1, IPC, LCD_CAM, LP_I2C0, PCNT, PERI_BACKUP, PSRAM, RMT, RTC_TIMER, SDHOST, SENSITIVE, UHCI0, ULP_RISCV_CORE, USB_FS, WCL
feather_rp2040Adafruit Feather RP2040
rp2040
Fullrp2040js, with flowRS's patches, in the page33 of 34VIRTUAL
longan_nanoSipeed Longan Nano
gd32vf103
CoreOnlyflowRS's pure-Rust RV32 hart, in the pagenot measured—
microbit_v2BBC micro:bit v2
nrf52833
FullflowRS's pure-Rust Cortex-M core, and Renode's tlib (built to wasm) for the FPU and DSP instructions it lacks, in the page61 of 70AAR, CCM, COMP, FPU, LPCOMP, MWU, NFCT, QDEC, USBD_ERRATA
nucleo_f401reST Nucleo-F401RE
stm32f401re
FullflowRS's pure-Rust Cortex-M core, and Renode's tlib (built to wasm) for the FPU and DSP instructions it lacks, in the page36 of 40I2S2, I2S3, SDIO, WWDG
nucleo_g071rbST Nucleo-G071RB
stm32g071rb
FullflowRS's pure-Rust Cortex-M core, in the page38 of 45CEC, DAC1, DMAMUX1, TAMP, UCPD1, UCPD2, WWDG
nucleo_h743ziST Nucleo-H743ZI
stm32h743zi
FullflowRS's pure-Rust Cortex-M core, and Renode's tlib (built to wasm) for the FPU and DSP instructions it lacks, in the page79 of 104CEC, COMP1, COMP2, CRS, DAC1, DCMI, DFSDM1, DLYB_QUADSPI, DLYB_SDMMC2, DMAMUX2, ETH, HRTIM1, JPEG, MDIOS, MDMA, OPAMP1, OPAMP2, SAI1, SAI2, SAI3, SAI4, SDMMC2, SPDIFRX1, VREFBUF, WWDG1
rpi_picoRaspberry Pi Pico
rp2040
Fullrp2040js, with flowRS's patches, in the page33 of 34VIRTUAL
rpi_pico2Raspberry Pi Pico 2
rp2350
FullflowRS's pure-Rust Cortex-M core, and Renode's tlib (built to wasm) for the FPU and DSP instructions it lacks, in the page34 of 51ACCESSCTRL, BOOTRAM, BUSCTRL, CORESIGHT_TRACE, DMA, GLITCH_DETECTOR, HSTX_CTRL, HSTX_FIFO, OTP, OTP_DATA, OTP_DATA_RAW, PIO0, PIO1, PIO2, SHA256, TRNG, VIRTUAL
sparkfun_thing_plus_rp2040SparkFun Thing Plus RP2040
rp2040
Fullrp2040js, with flowRS's patches, in the page33 of 34VIRTUAL
wio_terminalSeeed Wio Terminal
samd51p19a
FullflowRS's pure-Rust Cortex-M core, and Renode's tlib (built to wasm) for the FPU and DSP instructions it lacks, in the page39 of 56AC, AES, CCL, DSU, EVSYS, FREQM, HMATRIX, I2S, ICM, PAC, PCC, PDEC, QSPI, RAMECC, SDHC0, SDHC1, TRNG

Whatever its rung, no twin models:

  • the electrical side of the pins: drive strength, rise times, analogue levels and loading
  • anything outside the chip that the board's wiring row does not describe
  • the air: a radio's registers and timing may be modelled, its transmissions are not