Registry
Widgets, drivers, boards and ingest dialects, each with the form contract as its badge. A registry of community code is an attack surface: a package can carry malware, and a flaw in the tool that installs packages can open every machine running it. A flowRS package does not get into a graph on its description. Five conditions are checked by a machine and recorded:
compiles: it compilestests: it passes its testsno_runtime_install: it installs nothing at runtimeno_undeclared_network: it opens no undeclared networkunits: it declares its units
No package outside the contract enters a graph. The editor, the MCP server and the server refuse a node (or an import) from a package unless the index holds a record for the exact SHA-256 of the package tree they run, signed by a key they trust, with every condition passed; the refusal names the reason: not in the index, a hash mismatch, unsigned, a bad signature, a failed condition, a condition not run.
How each condition is checked
The verifier builds the package offline against flowRS's own crates and
Cargo.lock, runs each of its test binaries and a program that reads its ports'
units from its code, all under the seatbelt flowRS's agent checker uses: no network, writes only
to the job's own directories, a test binary may start nothing. Every denial is tagged, and the
kernel's report of it is read back; a denial planted by the verifier itself (a canary) must
reach the log, or the observed half of a condition is not run, never passed.
- compiles, tests: observed (the build's exit; each test's result; every test the manifest names must run and pass).
- installs nothing at runtime: observed (a program started, a write outside its directories, during its build or its runs) and static (a crate flowRS's lock does not pin, a git or foreign path dependency, a procedural macro, a process or library-loading call in its Rust, its build script included).
- opens no undeclared network: observed (a socket or a name lookup, during its build or its runs, to a port it did not declare) and static (a socket API or a network crate, when it declares no network).
- declares its units: its code's declaration of every port read
(
units::decl_for, what the graph checker holds a wire to), compared with its manifest; a number whose unit nothing declares fails.
Each record names the toolchain and the flowRS commit, and is signed with flowRS's hybrid signature, Ed25519 and ML-DSA-65 both required. The editor checks an archive's hash and its record's conditions itself, and asks the server to check the signature (ML-DSA has no browser build); the index it was built with is checked when it is built.
The packages
board-pico-w 0.1.0 · board
Raspberry Pi Pico W: the Pico's RP2040, UF2 flashing and header pins, none of them the GPIOs its CYW43439 radio takes.
- passedit compiles (observed) — it builds offline, confined, against flowRS's crates and lock (2 test binaries)
- passedit passes its tests (observed) — 4 passed, each binary confined (4 named in the manifest, all passed); 0 ignored; doc tests are not run
- passedit installs nothing at runtime (observed + static) — no program started and nothing written outside its directories, built and run confined; every crate is one flowRS's lock pins; no process or library loading in its Rust (239 other denials, reads and lookups, recorded)
- passedit opens no undeclared network (observed + static) — no socket and no name lookup, built and run with the network denied; no socket API or network crate in its Rust
- passedit declares its units (observed + static) — 5 ports read from its code, each declared, each as the manifest says
dialect-opentap 0.1.0 · dialect
OpenTAP TestPlan import: steps flowRS understands become nodes, every other step is carried foreign and counted in the coverage report. Export is refused rather than approximated.
- passedit compiles (observed) — it builds offline, confined, against flowRS's crates and lock (2 test binaries)
- passedit passes its tests (observed) — 8 passed, each binary confined (8 named in the manifest, all passed); 0 ignored; doc tests are not run
- passedit installs nothing at runtime (observed + static) — no program started and nothing written outside its directories, built and run confined; every crate is one flowRS's lock pins; no process or library loading in its Rust (509 other denials, reads and lookups, recorded)
- passedit opens no undeclared network (observed + static) — no socket and no name lookup, built and run with the network denied; no socket API or network crate in its Rust
- passedit declares its units (observed + static) — 5 ports read from its code, each declared, each as the manifest says
driver-bme280 0.1.0 · driver
Bosch BME280 humidity, pressure and temperature sensor over I2C: the BMP280 map flowRS ships, with the BME280's chip id, humidity control and reading, and config register.
- passedit compiles (observed) — it builds offline, confined, against flowRS's crates and lock (2 test binaries)
- passedit passes its tests (observed) — 5 passed, each binary confined (5 named in the manifest, all passed); 0 ignored; doc tests are not run
- passedit installs nothing at runtime (observed + static) — no program started and nothing written outside its directories, built and run confined; every crate is one flowRS's lock pins; no process or library loading in its Rust (215 other denials, reads and lookups, recorded)
- passedit opens no undeclared network (observed + static) — no socket and no name lookup, built and run with the network denied; no socket API or network crate in its Rust
- passedit declares its units (observed + static) — 14 ports read from its code, each declared, each as the manifest says
neuroviz 0.1.0 · widget
The neuro views: topomaps, butterfly plots with global field power, ERP images, Morlet time-frequency maps and compressed spectral arrays, one kernel at both tiers, checked against MNE's arrays.
- passedit compiles (observed) — it builds offline, confined, against flowRS's crates and lock (5 test binaries)
- passedit passes its tests (observed) — 16 passed, each binary run alone under seatbelt (3 named in the manifest, all passed); 0 ignored; doc tests are not run
- passedit installs nothing at runtime (observed + static) — no program started and nothing written outside its directories, built and run confined; every crate is one flowRS's lock pins; no process or library loading in its Rust (17020 other denials, reads and lookups, recorded)
- passedit opens no undeclared network (observed + static) — no socket and no name lookup, built and run with the network denied; no socket API or network crate in its Rust
- passedit declares its units (observed + static) — 19 ports read from its code, each declared, each as the manifest says
node-scale 0.1.0 · widget
Scale: out = in × gain. The worked example of a widget defined outside flowRS's core.
- passedit compiles (observed) — it builds offline, confined, against flowRS's crates and lock (1 test binaries)
- passedit passes its tests (observed) — 1 passed, each binary confined (1 named in the manifest, all passed); 0 ignored; doc tests are not run
- passedit installs nothing at runtime (observed + static) — no program started and nothing written outside its directories, built and run confined; every crate is one flowRS's lock pins; no process or library loading in its Rust (435 other denials, reads and lookups, recorded)
- passedit opens no undeclared network (observed + static) — no socket and no name lookup, built and run with the network denied; no socket API or network crate in its Rust
- passedit declares its units (observed + static) — 2 ports read from its code, each declared, each as the manifest says
Machine-readable: /registry/index.json
(flowrs.registry.index/1), each archive and record beside it, named by its hash.
Records are signed by v2:fa1a50ef56073d416f25e62fa6c5e7ef069f20766a1ef48ea0ec91d241df89cf.
Submitting a package
Submissions are open, by pull request to the public engine repository. Nothing on this site takes an
upload. A package is a crate with a flowrs-package.toml beside its
Cargo.toml: its kind, name, version and licence, what it provides, its declared
network and filesystem needs, the unit of every port, and the tests that must run. It is
self-contained: it inherits nothing from a workspace, and depends on flowRS crates by name.
flowrsc pkg pack <dir> # the archive and its content address
flowrsc pkg check <dir> # every check that runs without the signing key
flowrsc pkg verify <dir> -o record.json # the badge, checked confined (macOS); unsigned
flowrsc pkg check <dir> --registry <reg> # is this exact tree admitted, and why not
Then what happens to your pull request, in this order. The package is verified in the sandbox on flowRS's build host: the same five conditions, whatever your machine reported. A person judges whether it benefits the project; that is the only other test, and the answer is said on the pull request. Only then is its record signed, on the maintainer's own machine, and published. The signing key has never been on the build host or on the server: verification, which builds code nobody has vetted, runs where the key is not.
flowrsc pkg submit <dir> --registry <reg> # on the build host: verify and stage, unsigned
flowrsc pkg sign --key <file> --registry <reg> # on the maintainer's machine: compiles and runs nothing
flowrsc pkg publish --registry <reg> # signed records in, index rebuilt
What you contribute stays yours under the licence you state in the manifest. See CONTRIBUTING.md.