Run a Rule Within Set Limits

Create complete source and input files, run both Native evaluators, and read success and resource outcomes.

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

CommandLanguage profileExample
lispex embedlispex/r7rs-rule-embedded-core/1Return "allow" or "deny"
lispex embed fulllispex/r7rs-rule-current-profile-bounded/1Return 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.

LISPEX
(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.

PYTHON
from pathlib import Path

Path("input.lpxvalue").write_bytes(bytes.fromhex("03 0000000000000002 3134"))
print("input.lpxvalue: 11 bytes (integer 14)")

Run the script.

SH
python make-input.py

It 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.

JSON
{
  "raw_source_bytes": 4096,
  "prepare_work": 1000000,
  "logical_allocation": 1000000,
  "syntax_depth": 64
}

Create evaluation-limits.json.

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.

SH
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.lpxembed

All 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.

JSON
{
  "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.

SH
lispex embed verify --artifact result.lpxembed

This 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.

LISPEX
(vector input (+ input 1))

Reuse the input and limit files from steps 1 and 2.

SH
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.lpxfull

All 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.

JSON
{
  "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.

SH
lispex embed full verify --artifact result.lpxfull
lispex embed full replay --artifact result.lpxfull

Each 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.

SH
lispex embed evaluate --prepared policy.lpxembed --input input.lpxvalue --limits evaluation-limits.json --out rerun.lpxembed

This 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.

JSON
{
  "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
}
SH
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.lpxfull

All 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

JSON
{
  "category": "semantic-exhausted",
  "code": "eval_work"
}

Full evaluator, selected fields

JSON
{
  "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.

Execution Conditions · Evaluator Reference