THE FHERMA CLI
Writing a testing bundle
The authored components of a testing bundle are written in a scaffolded directory. The cycle is four commands.
Scaffold
fherma testing init polynomial-multiplication/negacyclic@1.0.0 fherma testing init polynomial-multiplication/negacyclic # latest published fherma testing init --signature ./sig.fhk # no platform involved
The platform is asked for one thing — the signature — and the scaffold is
built locally by fherma-lang; with --signature no network is touched at
all. What lands:
negacyclic-1.0.0/ ├── fherma.toml generated — which specification this belongs to ├── fherma.py generated — Point, Inputs, Outputs, Stream, Tensor ├── main.py generated — the bundle's command line: make · verify · info ├── README.md generated — the signature, and what to write ├── generate.py yours ├── oracle.py yours ├── verify.py yours, and usually unnecessary ├── vectors/ worked examples, for accepting the oracle └── assets/ data files the three functions may read
The types in fherma.py are derived from the signature; the author
declares no types. Write generate.py and oracle.py; verify.py is
required only when the comparison rule is not exact equality.
Name parts to scaffold one or two: --generator, --oracle, --verifier.
When the specification's signature moves, fherma testing init --update
rewrites the generated files and never touches yours.
Check
fherma testing inspect # read the three without running them fherma testing inspect oracle
Static checks: the file parses, the entry point exists with the right
arity, the scaffolded stub has been replaced. Checks that require execution
are reported as not run, not omitted.
Run
fherma testing run generator --point '{"N": 8, "W": 2}' --seed 7
fherma testing run generator --point '{"N": 8, "W": 2}' --twice # determinism
fherma testing run oracle --point '{"N": 8, "W": 2}' --seed 7
Each command runs the component in a child process with a time and memory
limit. The output is a description — shapes, sizes, the first few values —
not the full data. --twice runs the generator twice at the same seed and
compares the results byte for byte: the determinism check.
The bundle is also an ordinary program — the same layout a runner uses:
python main.py make /tmp/p --point '{"N": 8, "W": 2}' --seeds 0-7
python main.py verify /tmp/p
Submit
fherma testing submit fherma testing submit --dry-run
The upload includes both authored and generated files, so the directory
stored on the platform is identical to the one tested locally. The response
reports each component's state and checks. fherma testing status reports
the same later, including whether the signature has changed since the
bundle was generated.