FS FormScript

Runtimes

A runtime is an implementation of the language: something that takes a document, runs the transactions against it, and produces an output document. The specification defines the language. A runtime is one answer to it.

There are three runtimes here, and they are not the same kind of thing.

Runtime Where it runs What it is
The reference implementation Node 20.19 or later the TypeScript packages in this repository — the one the specification's §18 suite is written against
The browser bundle a browser, as ES modules the same implementation, compiled and loaded natively. Not a second implementation
The Kotlin runtime the JVM, Java 21 a second implementation, in another language, in another repository

The second row is the one to be careful about. The playground on this site is the reference implementation compiled to the browser, so it is the same code answering in a different environment. That is a deployment, not a second opinion, and it is never counted as one.

The reference implementation

The packages in this repository. It is the implementation the §18 suite is written against, and the one that declares a conformance level.

bash
npm run formscript -- level      # what it claims, and what backs the claim
npm run formscript -- conformance # the §18 suite, on its own

Its declared level is 3, and the declaration lives in conformance.json at the root of the repository. It is checked rather than asserted: the command re-reads §6.4 from the specification, compares its builtin list with the evaluator's, and reports every level against what the repository actually contains. A test fails if the declared level is not supported.

The Kotlin runtime

A second implementation of the same specification, in another language, in the repository bazokhan/formscript-kotlin. It was written against the specification, not against the TypeScript code.

It is held to a pinned revision of the specification. The pin is three hashes and a commit, and the suite checks every one of them:

The pin names Value at r19
The revision 19
The specification file 4b09eeb06041096e5990899e037dbb37d41457e8518a0e607373a85e063d4f51
The fixture manifest 667b9f839fabb1dfb317a0b76823ec571d59b86f5e859b7f519d263593894f16
The commit the fixtures came from 5bd9d867e3fe0acbbfef082a22e01f7ab72c99c0

Change one number and the suite fails. That is deliberate: a second implementation is judged against the words of one revision of the specification, and the revision moves only when the implementation moves with it.

The instruments

What a runtime is judged by, and what each instrument is worth.

Instrument What it is Independent of the reference implementation?
The §18 suite 112 rows read from the specification text at run time: 50 documents that must parse, 24 that must be rejected with a named code, 32 evaluation rows, 5 that must compile, and the flagship end to end Yes. The rows are written in the specification, so a row added to §18.3 is picked up by the next run — there is no second copy to keep in step
The oracle 4 corpus documents whose expected outputs were written by hand out of the specification, each one citing the statement that gives it Yes. This is the instrument that makes the second runtime a second reading rather than a second copy
The corpus 232 real forms from FHIR and XForms, each run empty and filled No. The corpus fixtures carry the reference implementation's own answers, so this is a differential test: it catches a divergence, not a shared misreading
The property suite 11 properties over the evaluator and the engine Partly. The properties are written in the reference repository's own tests

That last column is the whole story of level 4, and it is worth being exact about.

Why level 4 is not claimed

Level 4 is multi-platform conformance to Spec-15.6: for a fixed document and a fixed script of transactions, two conforming runtimes must produce identical field values, validity states, validation error codes and output documents.

The Kotlin runtime passes the §18 suite, the corpus and the oracle. So the evidence is there — but the level is still not claimed, for two reasons.

The declaration is per-implementation. conformance.json declares platforms: ["node"], and the level check marks level 4 met only when there is more than one. This repository contains one runtime on one platform. The Kotlin runtime is a separate repository with its own declaration, and it declares no level either. Neither repository may claim for itself what the other would have to prove.

Most of the cross-runtime evidence is differential. The corpus is 232 forms, and its expected outputs are the reference implementation's own answers. If both implementations misread the same sentence of the specification, the corpus would agree and the misreading would go unnoticed. The independent instruments are the 112 rows of §18 and the four documents of the oracle. Extending the oracle across the corpus is the next step, and it is an obligation this repository carries openly.

An unbacked claim of level 4 would be worse than no claim at all.

See also