You can run a rule with explicit resource limits and inspect its outcome file. This guide uses the decision evaluator for a string result and the full evaluator for a vector result. A set of such limits is called a resource profile.
Install Native Lispex and Python 3. Use a new working directory. Save the text files as UTF-8 with LF line endings. The commands create new output files, so use unused output names when repeating them.
Choose the evaluator
| Command | Language profile | Example |
|---|---|---|
lispex embed | lispex/r7rs-rule-embedded-core/1 | Return "allow" or "deny" |
lispex embed full | lispex/r7rs-rule-current-profile-bounded/1 | Return a vector using the full set of 205 primitive procedures |
These are separate evaluator products. Each preparation or evaluation uses a fresh instance with its own memory and resource usage counters. Both execute WASM modules with zero imports.
1. Create the source and input
Save this complete decision rule as policy.lspx. The evaluator binds the input
value to input.
(if (< input 15) "allow" "deny")The rule returns "allow" for integer input 14. Create make-input.py to write
that integer in the binary lispex.embed-value/v1 format.
from pathlib import Path
Path("input.lpxvalue").write_bytes(bytes.fromhex("03 0000000000000002 3134"))
print("input.lpxvalue: 11 bytes (integer 14)")Run the script.
python make-input.pyIt prints the following line, creates input.lpxvalue, and exits with code 0.
input.lpxvalue: 11 bytes (integer 14)The file contains all 11 bytes shown in the script. The first byte marks an exact
integer. The next eight give the length 2, and the last two contain the UTF-8
text 14. An ordinary JSON file uses a different encoding.
2. Set preparation and evaluation limits
Create prepare-limits.json.
{
"raw_source_bytes": 4096,
"prepare_work": 1000000,
"logical_allocation": 1000000,
"syntax_depth": 64
}Create evaluation-limits.json.
{
"canonical_input_bytes": 4096,
"eval_work": 1000000,
"logical_allocation": 1000000,
"semantic_frames": 1000,
"traversal_depth": 256,
"output_bytes": 1000000,
"diagnostic_bytes": 1000000,
"transcript_bytes": 1000000,
"transcript_events": 100,
"result_bytes": 1000000
}prepare_work limits preparation work. eval_work limits evaluation work.
logical_allocation counts allocation units defined by the evaluator's resource
model. It is separate from the WASM memory limit. The other fields limit
input size, depth, output, diagnostics, the event transcript, and the result.
A transcript records the ordered events of an evaluation.
3. Run the decision rule
Preparation reads UTF-8, expands shorthand forms, builds and verifies bytecode, and checks the selected language profile. It records the source, semantic rule, feature set, bytecode, evaluator, and preparation limits.
lispex embed prepare --source policy.lspx --limits prepare-limits.json --out policy.lpxembed
lispex embed evaluate --prepared policy.lpxembed --input input.lpxvalue --limits evaluation-limits.json --out result.lpxembed
lispex embed inspect --artifact result.lpxembedAll three commands exit with code 0. prepare creates policy.lpxembed;
evaluate creates result.lpxembed. Both are silent. inspect prints this JSON
without creating a file. It is formatted here for reading.
The JSON identifies the evaluator, rule, input, and completed outcome.
semantic-complete means the rule completed. inspect reports status and
identifiers; the encoded returned value is inside result.lpxembed.
The hashes below apply to the exact example bytes, including the final LF in the source.
The outcome file keeps preparation and evaluation limits separate. Its inspection JSON summarizes identifiers and status rather than listing the resource usage counters.
{
"abi_id": "lispex.embed-wasm-abi/v1",
"bytecode_sha256": "4d3707ba9a0b64f5165ebd0996dd8b2fa5bf4c958f7afbc9062203f46f8eb068",
"canonical_input_sha256": "4892c71b4803d6f2057433116b87927c62eed7754252cd5048a8663903cf6e2c",
"canonical_source_sha256": "a8cc61bac9abf9d6f8647a529402d348a4d045f1006f3b4c67f21adefa33743e",
"category": "semantic-complete",
"code": "complete",
"engine_artifact_sha256": "fa6e52559e1f5a43e50a3b7ac0cc5add6930cff0aed8aaff462cff4609362870",
"feature_set_sha256": "c7ac2d3037b43dd90889467aabdcd2d3c061559bde12bb8330d878886c5ab429",
"model_id": "lispex-vm-meter/1",
"operation": "evaluate",
"payload_bytes": "23",
"portable": true,
"portable_core_bytes": "1900",
"portable_core_sha256": "9949d0c240c3e641cbee652c7d05d32612414759e77bbf3d5d91ff63b2bdfd5f",
"receipt_schema_id": "lispex.embed-receipt-core/v1",
"schema": "lispex.embed-artifact-inspection/v1",
"semantic_profile_id": "lispex/r7rs-rule-embedded-core/1",
"semantic_rule_sha256": "2419de25f5fcec98e74d9119c28687ab5b440be322502f8f7b24cec19424dc22",
"submission_sha256": "aa9f358366f58ab0fbc36c93c974b27ce908a10eb0898ad9313e756072d6552f",
"submitted_source_sha256": "30a60354485c671766d6a7196b3418529304f3feae6ca040999715fd90f9f847",
"vouch_eligible": false
}Check the stored result.
lispex embed verify --artifact result.lpxembedThis prints the same JSON and exits with code 0. It checks the artifact's
structure, hashes, values, and portable core, plus the built-in evaluator identity.
The portable core is a transferable record that binds one execution to its inputs
and outcome. verify creates no files.
4. Run the full evaluator
Save this complete source as full-policy.lspx. It uses vector from the full
language profile and returns #(14 15) for the same input.
(vector input (+ input 1))Reuse the input and limit files from steps 1 and 2.
lispex embed full prepare --source full-policy.lspx --limits prepare-limits.json --out policy.lpxfull
lispex embed full evaluate --prepared policy.lpxfull --input input.lpxvalue --limits evaluation-limits.json --out result.lpxfull
lispex embed full inspect --artifact result.lpxfullAll three commands exit with code 0. The first two are silent and create
policy.lpxfull and result.lpxfull. inspect creates no files and prints the
following JSON, formatted here. The full evaluator names a successful outcome
complete.
{
"abi_id": "lispex.embed-wasm-abi/v1",
"category": "complete",
"code": "complete",
"component_id": "lispex-evaluator/rust-vm-current-profile/1",
"engine_artifact_sha256": "dd4cde2976d825ae99b542d308d87489ac96848e0710329dbb9173664d8c5ad8",
"fallback_count": 0,
"kind": "evaluate",
"model_id": "lispex-full-vm-meter/1",
"portable_core_assigned": true,
"portable_core_bytes": "1932",
"portable_core_sha256": "1201ac2939e678db7926d160deb4ccb4a566a5d74b15fe19076bdd48bd88e730",
"receipt_schema_id": "lispex.embed-receipt-core/v1",
"replayable": true,
"request_sha256": "05d3c7bb9ee45728e8dcd6f84e974e76d225c3cd1c77799332fd8d12ff25bcb3",
"schema": "lispex.full-embed-artifact/v0",
"semantic_profile_id": "lispex/r7rs-rule-current-profile-bounded/1",
"source_retained": false,
"value_codec_id": "lispex.embed-value/v1",
"vouch_eligible": false
}Verify the result, then replay its recorded request in a fresh instance.
lispex embed full verify --artifact result.lpxfull
lispex embed full replay --artifact result.lpxfullEach command prints the same full-evaluator JSON shown above, exits with code
0, and creates no files. Replay checks the recorded response and portable core.
Keep the original source separately; the full artifact records its identity and
prepared program.
To repeat a decision evaluation, supply its prepared file, input, and limits again.
lispex embed evaluate --prepared policy.lpxembed --input input.lpxvalue --limits evaluation-limits.json --out rerun.lpxembedThis command is silent, creates rerun.lpxembed, and exits with code 0.
For a decision directory with a replay command, follow
Decision Rules.
5. Read a resource stop
Create low-work-limits.json with the complete contents below. Only eval_work
changes from step 2.
{
"canonical_input_bytes": 4096,
"eval_work": 0,
"logical_allocation": 1000000,
"semantic_frames": 1000,
"traversal_depth": 256,
"output_bytes": 1000000,
"diagnostic_bytes": 1000000,
"transcript_bytes": 1000000,
"transcript_events": 100,
"result_bytes": 1000000
}lispex embed evaluate --prepared policy.lpxembed --input input.lpxvalue --limits low-work-limits.json --out exhausted.lpxembed
lispex embed inspect --artifact exhausted.lpxembed
lispex embed full evaluate --prepared policy.lpxfull --input input.lpxvalue --limits low-work-limits.json --out exhausted.lpxfull
lispex embed full inspect --artifact exhausted.lpxfullAll four commands exit with code 0. Each evaluate is silent and creates its
named exhausted file. Each inspect prints a JSON report. These are the fields
that identify the outcome in those reports.
Decision evaluator, selected fields
{
"category": "semantic-exhausted",
"code": "eval_work"
}Full evaluator, selected fields
{
"category": "exhausted",
"code": "eval_work"
}eval_work identifies the exhausted resource. The zero work limit stops evaluation
before it produces the rule's value. Exit code 0 means the outcome file was
written successfully; category tells you whether the rule completed.
Use the result in an application
The outcome file binds the rule, input, selected limits, evaluator, transcript, and result. Decision exchange adds signed record containers and recipient policy. Lispex Vouch authenticates signed evidence and evaluates a local decision gate. The calling application decides on network access and business actions.