Skip to content

Verified: Function blocks, libraries, and tasks

Each claim the Function blocks, libraries, and tasks page makes, with the tests that prove it in the last green CI run: 6 of 18 verified, 2 with no test yet. The claims live in docs/claims/blocks-and-tasks.yaml.

Last green CI run 16 Oct 2026, 14:48 UTC on c7618d3 · all runtime claims

TASK-001 partly verified

Library files (TYPE, FUNCTION, FUNCTION_BLOCK declarations) passed as Options.Libraries compose ahead of the program, and a FUNCTION_BLOCK instance keeps its own state per instance across scans.

where the docs say so · Per-instance state isolation (two instances of one block not sharing a VAR) is not asserted at this level; the language-level tests in lang/st cover FB instance semantics.

TASK-002 partly verified

A user FUNCTION_BLOCK instantiates from an FBD diagram exactly like a built-in block, and a .ld or .fbd file holding FUNCTION_BLOCKs is a library the same as a .st one.

where the docs say so · An FBD-authored library block is not exercised separately from the ladder one.

  • pass TestLibrariesUserFBFromFBD in runtime
  • pass TestLadderLibraryComposes in internal/project
  • pass TestComposeGraphicalProgramUsesLadderLibrary in cmd/naut

TASK-003 partly verified

The tooling composes libraries byte-identically to the runtime: naut compose, check, test and pull see the same prelude the runtime boots with.

where the docs say so · The LSP and `naut pull` sides are not asserted against the runtime composition here.

TASK-004 verified

A block's VAR section persists across scans, and a warm online edit carries instance state across the swap by name and type (a PI keeps its integral).

where the docs say so · A user FUNCTION_BLOCK (Totalizer) keeps its integrated Sum across a warm swap that edits its body, and a type change resets.

  • pass TestSwapWarmCarriesRetainedState in runtime
  • pass TestSwapWarmTypeChangeResets in runtime

TASK-005 partly verified

In a manifest project, any .st, .ld or .fbd file with no PROGRAM in the project root or anywhere under lib/ (at any depth) is a library, and all of them compose into one prelude ahead of every task.

where the docs say so · Root libraries (.st and .ld) and nested lib/ libraries are asserted to compose, and a root library block reaches a second task (both tasks of TestBuiltControllerActivatesWarm instantiate it). A PROGRAM-less .fbd library file is never exercised.

TASK-006 partly verified

The prelude order is fixed: .st libraries first, then transpiled .ld/.fbd ones, each group sorted by project-relative path.

where the docs say so · The tier order (.st before transpiled .ld, even when the .ld sorts first alphabetically) is asserted. Path sorting within a group is seen only for two .st files under lib/ and a single .ld, so root and lib/ files interleaving by project-relative path (lib/pump.st before a root units.st) and ordering within the graphical group are not asserted; no .fbd library is exercised.

TASK-007 verified

A block declared in both the root and lib/ is the same duplicate-name error as declaring it in two root files.

where the docs say so

TASK-008 verified

lib/ holds libraries only: a file under lib/ that declares a PROGRAM is an error naming the file.

where the docs say so

TASK-009 partly verified

No other folder composes: hmi/, tags/, deploy/, node_modules/ and any other subdirectory are ignored however many .st files they hold.

where the docs say so · tags/ is asserted (its redeclared block would be a duplicate-name error) and hmi/ is asserted by the fixture's hmi/ignored.st staying out of the library list and naut compose; deploy/ and node_modules/ are never exercised. The hmi/x.st PROGRAM in TestOtherSubdirsStayIgnored alone could not fail, since a stray PROGRAM file outside lib/ is not an error either way.

TASK-010 verified

naut build ships lib/ inside the binary, and errors in library files are named by their project path (lib/motor.ld).

where the docs say so

TASK-011 partly verified

Several programs run as tasks at their own rates against one shared tag store, each with its own measured-dt tag, with no calling between them; the main task owns field I/O.

where the docs say so · Only the main task reading inputs and writing outputs is asserted; extra tasks touching I/O is not.

  • pass TestTasks in runtime
  • pass TestTasksRunConcurrently in runtime
  • pass TestRuntimeDrivesOutputs in runtime

TASK-012 verified

Each scan copies its program's external tags in, executes privately and commits what changed as one unit, so a reader never sees a scan half-done and a fast task never waits behind a slow one.

where the docs say so

  • pass TestScanViewSnapshotAndCommit in runtime
  • pass TestScanCommitsAreAtomic in runtime
  • pass TestFastTaskDoesNotWaitForSlowTask in runtime

TASK-013 no test yet

Two tasks writing the same tag resolve by commit order (last wins).

where the docs say so · Gap. No test has two tasks write one tag and asserts which value survives.

TASK-018 verified

Tags are all that tasks share: a program's own variables, its function-block instances among them, are private to it. Naming another task's instance is a compile error that says to publish the value to a tag in the owner, and a reader sees that tag as of the owner's last committed scan.

where the docs say so · Added out of numbering order with #327; it sits where the page makes it. Asserted for function-block instances (ST and ladder readers, through the program's and the task's name) and for a plain VAR.

TASK-014 partly verified

Each additional task's health is reported in Stats().Tasks and rendered in the built-in dashboard and the HMI kit's ScanDiagnostics.

where the docs say so · TestTasks asserts a task's row in Stats().Tasks with its scan count and zero logic errors. Overruns, a task's fault reaching its row, and the dashboard / ScanDiagnostics rendering are not asserted. (The earlier refs TestScanStatsDiagnostics, TestMainTaskFaultKeepsMessage and TestFrameCarriesScanDiagnostics test the main task's stats only, and "a fault is kept as its message" is not a promise of the page.)

TASK-015 partly verified

A task's cpu: pins its thread to a core and priority: runs it under SCHED_FIFO (Linux); the placement is reported in the stats.

where the docs say so · The FIFO grant is skipped on CI hosts without CAP_SYS_NICE.

  • pass TestApplySchedAffinity in runtime
  • pass TestRunReportsSched in runtime

TASK-016 partly verified

A placement request the OS refuses is logged and shown as REFUSED on the task's row, and the task runs normally rather than silently falling back.

where the docs say so · The dashboard REFUSED label itself is not asserted.

  • pass TestApplySchedFIFORefusalIsExplicit in runtime
  • pass TestRunReportsSched in runtime

TASK-017 no test yet

Pinning alone on a stock kernel makes a fast task worse; it should be used together with an isolated core or a real-time priority.

where the docs say so · Gap, and not a test-shaped claim; it rests on the measurements in the real-time guide.